# What Is the Certificate Expiration Policy in mkcert?

> Discover mkcert's certificate expiration policy. Learn about end-entity certs expiring in 2 years 3 months and root CA certs in 10 years for secure local development.

- Repository: [Filippo Valsorda/mkcert](https://github.com/FiloSottile/mkcert)
- Tags: deep-dive
- Published: 2026-03-05

---

**mkcert generates end-entity certificates valid for 2 years and 3 months (approximately 825 days) and root CA certificates valid for 10 years, with both becoming effective immediately upon creation.**

When you use [FiloSottile/mkcert](https://github.com/FiloSottile/mkcert) to create locally-trusted TLS certificates, the tool enforces specific validity periods that balance security requirements with platform compatibility. Understanding these defaults helps you plan certificate rotation schedules and troubleshoot expiration-related errors in development environments.

## How mkcert Determines Certificate Expiration

mkcert creates two distinct certificate types, each with hardcoded validity periods defined in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go).

### End-Entity (Leaf) Certificate Validity

When you run `mkcert example.com`, the tool generates a leaf certificate valid for **2 years plus 3 months** (approximately 825 days). In [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go) lines 59-63, the expiration is calculated using:

```go
expiration := time.Now().AddDate(2, 3, 0)

```

This duration is deliberately chosen to remain **under Apple's 825-day limit** for all TLS certificates, including custom roots. The resulting `NotAfter` date ensures compatibility with macOS and iOS platforms that enforce strict certificate lifetime restrictions.

The leaf certificate generation occurs in the `(*mkcert).makeCert` method (and `makeCertFromCSR` for CSR-based workflows). After setting `NotBefore: time.Now()`, the code assigns the calculated expiration to the certificate template before signing. mkcert also prints the expiration date to the console when the certificate is created.

### Root CA Certificate Validity

The locally generated root CA that mkcert installs in your system trust store is valid for **10 years**. This extended period is defined in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go) lines 40-42 within the `(*mkcert).newCA` function:

```go
NotAfter: time.Now().AddDate(10, 0, 0)

```

The CA certificate is marked with `IsCA: true` and `KeyUsageCertSign`, allowing it to sign multiple leaf certificates throughout its decade-long lifespan. The generated CA is stored in the **CAROOT** directory (viewable via `mkcert -CAROOT`) and persists across individual leaf certificate generations.

## Why the 2-Year, 3-Month Duration?

Apple's security requirements mandate that all TLS certificates issued after September 2020 have a validity period not exceeding 825 days. By setting leaf certificates to expire at 2 years and 3 months (approximately 825 days), mkcert ensures compliance with these restrictions while maximizing the usable lifetime of development certificates.

This calculation applies universally to all certificates generated by the tool, regardless of the specific domains or IPs specified in the command.

## Verifying Certificate Expiration Dates

You can inspect the validity periods of generated certificates using standard OpenSSL commands.

To check a leaf certificate's expiration:

```bash
mkcert example.com
openssl x509 -in example.com.pem -noout -dates

```

The output will show `notBefore` set to the current time and `notAfter` set approximately 2 years and 3 months later.

To verify your root CA's expiration date:

```bash
openssl x509 -in "$(mkcert -CAROOT)/rootCA.pem" -noout -dates

```

This displays the 10-year validity window from the CA's creation date.

## Summary

- **Leaf certificates** generated by `mkcert <domain>` expire after **2 years and 3 months** (≈825 days) to comply with Apple's certificate lifetime limits.
- **Root CA certificates** created during `mkcert -install` remain valid for **10 years** to enable long-term signing operations.
- Both certificate types use `time.Now()` for their `NotBefore` field, becoming valid immediately upon creation.
- The expiration logic is implemented in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go) within the `makeCert` and `newCA` functions.

## Frequently Asked Questions

### How long are certificates generated by mkcert valid?

mkcert leaf certificates are valid for 2 years and 3 months (approximately 825 days), while the root CA certificate remains valid for 10 years. These durations are hardcoded in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go) and cannot be configured via command-line flags.

### Does the mkcert root CA expire?

Yes, the root CA certificate expires after 10 years from the moment of creation. After expiration, you must generate and install a new CA using `mkcert -install`, which will require re-generating and re-trusting all leaf certificates in your development environment.

### Why does mkcert use 2 years and 3 months instead of a round number?

The 2-year, 3-month duration (approximately 825 days) specifically accommodates Apple's 825-day maximum certificate lifetime restriction enforced on macOS and iOS. This ensures that locally-trusted certificates work seamlessly across all Apple platforms without triggering security warnings.

### Can I change the default expiration period in mkcert?

No, mkcert does not provide configuration options to modify certificate validity periods. The tool intentionally hardcodes these values in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go) (lines 40-42 for the CA and lines 59-63 for leaf certificates) to enforce secure defaults and platform compatibility. To use custom expiration dates, you would need to modify the source code and rebuild the binary.