Why Are mkcert Certificates Valid for Less Than 825 Days? Apple Compatibility Explained
mkcert deliberately generates TLS certificates with a maximum validity of approximately 825 days (2 years and 3 months) to comply with Apple's platform security policies, which automatically reject any certificate valid for more than 825 days.
mkcert is a widely-used development tool created by FiloSottile that simplifies the creation of locally-trusted TLS certificates. When you generate certificates using mkcert, the expiration date is intentionally capped to ensure seamless operation on macOS and iOS devices. This design choice directly addresses strict Apple certificate validity limits that apply to all credentials, including custom root CAs installed for local development.
Understanding Apple's 825-Day Certificate Limit
Apple's platform security requirements mandate that all TLS certificates must have a validity period of 825 days or fewer. This restriction applies universally across macOS, iOS, iPadOS, and watchOS, affecting both publicly-trusted certificate authorities and locally-installed development roots.
According to Apple Support article HT210176, this policy ensures cryptographic credentials rotate regularly, limiting exposure windows for compromised certificates. Apple operating systems automatically reject certificates exceeding this limit, rendering them invalid regardless of their trust chain.
How mkcert Implements the Expiration Constraint
In the mkcert source code, the certificate expiration logic is explicitly designed to stay below Apple's threshold. The implementation resides in the core certificate generation logic and uses Go's standard library time calculations to ensure compliance.
The cert.go Implementation
In cert.go at lines 59–62, mkcert calculates the NotAfter field using precise date arithmetic that guarantees Apple compatibility:
// cert.go#L59-L62
// Always less than 825 days, the limit that macOS/iOS apply to
// all certificates, including custom roots.
// https://support.apple.com/en-us/HT210176
notAfter := time.Now().AddDate(2, 3, 0)
The AddDate(2, 3, 0) function adds 2 years and 3 months to the current timestamp, resulting in a validity period of approximately 825 days. The inline comment explicitly documents this choice as necessary for macOS and iOS compatibility. This function is invoked by the CLI entry point in main.go, which coordinates the certificate creation process through the makeCert function.
Verifying Certificate Validity Periods
When you generate a certificate using mkcert, you can verify the exact expiration date using standard OpenSSL commands. The tool automatically applies the 825-day constraint to every certificate it issues, ensuring consistent behavior across platforms.
# Generate a certificate for local development
mkcert localhost
# Inspect the certificate dates
openssl x509 -noout -dates -in localhost.pem
Typical output:
notBefore=Mar 5 15:22:45 2026 GMT
notAfter=Jun 5 15:22:45 2028 GMT
The notAfter date reflects the 2-year, 3-month window calculated in the source code. This predictable expiration ensures your development certificates remain valid across all Apple platforms without triggering "certificate expired" warnings.
Summary
- mkcert limits certificate validity to approximately 825 days (2 years + 3 months) to comply with strict Apple platform requirements.
- The expiration logic is hardcoded in
cert.gousingtime.Now().AddDate(2, 3, 0)with explicit comments referencing Apple's 825-day policy. - Apple enforces this limit on all certificates, including custom root CAs installed for local development on macOS and iOS.
- You can verify the expiration period using
openssl x509commands on any generated certificate file.
Frequently Asked Questions
Why does Apple enforce an 825-day certificate limit?
Apple imposes the 825-day maximum validity period to enhance security by ensuring cryptographic credentials rotate regularly. This policy reduces the risk associated with compromised certificates and aligns with industry standards for certificate lifecycle management. The restriction applies universally to all TLS certificates trusted by macOS and iOS, including development certificates issued by tools like mkcert.
Can I override mkcert's 825-day expiration limit?
No, the 825-day limit is hardcoded in the mkcert source code within cert.go. The certificate generation logic uses a fixed calculation of time.Now().AddDate(2, 3, 0) to determine the NotAfter date. To use different expiration dates, you would need to fork the repository and modify the source code directly, though this would break compatibility with Apple devices and is not recommended for cross-platform development.
Does the 825-day limit affect non-Apple platforms?
While the 825-day limit is specifically enforced by Apple's operating systems, mkcert applies this constraint universally to all generated certificates. This ensures consistent behavior across development environments and prevents scenarios where certificates work on Linux or Windows but fail validation on macOS or iOS. The uniform approach simplifies cross-platform development workflows and eliminates platform-specific certificate debugging.
What happens when an mkcert certificate expires after 825 days?
Once an mkcert certificate reaches its expiration date (2 years and 3 months after creation), browsers and operating systems will reject it as invalid. You must regenerate the certificate using mkcert <hostname> to create a new valid credential. Since mkcert maintains its root CA in your system trust store, regeneration is immediate and automatically trusts the new certificate without requiring additional installation steps.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →