Finds the 365-day and 90-day certificate assumptions left in your cert-manager, Terraform, ACME and monitoring config. The public TLS maximum is 200 days now, 100 on 2027-03-15, 47 on 2029-03-15.
Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.
npmDocker Hubnpx @readystack/cert-lifetime-lint-47day <file> docker run --rm -v "$PWD:/w" getreadystack/cert-lifetime-lint-47day /w
Team? One key for every ReadyStack linter, 5 seats, $149 once
This page is the working piece. The full pack has everything below.
Finds the 365-day and 90-day certificate assumptions left in your cert-manager, Terraform, ACME and monitoring config. The public TLS maximum is 200 days now, 100 on 2027-03-15, 47 on 2029-0
Hosted certificate monitors bill $17-19 every month - Better Stack Starter is $204/year for 20 domains and TrackSSL Starter is $19/month - and they watch a certificate after it has been issued, not the config that issues it.
Buy the full version — $29· ReadyStack
Real numbers from this tool, line by line.
Four lines in one cert-manager manifest are all it takes to make a production certificate un-issuable, and the platform engineer who owns that file usually does not learn it until a renewal quietly fails.
Here is the manifest. Every line in it was correct in 2025.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api-prod-tls
spec:
secretName: api-prod-tls
duration: 8760h # 365 days
renewBefore: 2400h # 100 days
dnsNames:
- api.example.com
Two of those lines are now wrong, and the reason is a date rather than a bug.
On 11 April 2025 the CA/Browser Forum passed Ballot SC-081v3 by 29 votes to zero, with Apple, Google, Mozilla and Microsoft all in favour. It puts the maximum lifetime of a publicly trusted TLS certificate on a ratchet:
| From | Max validity | Max DCV reuse |
|---|---|---|
| before 2026-03-15 | 398 days | 398 days |
| 2026-03-15 | 200 days | 200 days |
| 2027-03-15 | 100 days | 100 days |
| 2029-03-15 | 47 days | 10 days |
The first step is already behind us. duration: 8760h is 365 days, which no public CA has been able to issue since 15 March 2026. renewBefore: 2400h is 100 days, which will be longer than the entire certificate from 15 March 2027 - and a renewBefore longer than the certificate makes cert-manager renew in a loop.
The second half of the problem is the renewal cadence, and it moves on a different calendar. Let's Encrypt switched its tlsserver profile to 45-day certificates on 13 May 2026, made a 160-hour shortlived profile generally available on 15 January 2026, and will switch the default classic profile to 64 days on 10 February 2027 and to 45 days on 16 February 2028. Anything renewing monthly gets exactly one attempt per certificate; anything renewing yearly is expired for 165 days out of every 365.
That arithmetic is the whole point. A renewal job on a yearly schedule against a 200-day maximum is not "slightly stale" - it is a service serving an expired certificate for 165 days a year.
The awkward part is that none of this is visible in a code review, because none of it is a syntax error. 8760h is a valid Go duration. validity_period_hours = 8760 is valid HCL. -days 365 is a valid openssl flag. They are all simply describing a certificate that cannot exist any more. And if you ask an AI assistant, most will still tell you the maximum is 398 days, or that Let's Encrypt is fixed at 90 days, because SC-081v3 landed after their training data.
So it is worth grepping for the assumption rather than the syntax. The places it hides:
duration and renewBefore on every Certificatevalidity_period_hours, early_renewal_hours-days, "expiry", --not-after, -validity@monthly, @yearly or OnCalendar=monthlypin-sha256 and hardcoded leaf fingerprints, which break on every rotationCert Lifetime Lint is 24 rules over exactly that list. You can paste a file into the free web version and see every finding with its line number, its severity and the date the limit changes - nothing withheld. The licensed version adds the parts that are about scale rather than answers: the whole repository in one pass, a CI gate so a pull request cannot reintroduce 8760h, an exported CSV/JSON/HTML audit for the change ticket, and in-place rewriting of the durations.
The next date is 15 March 2027, when the maximum halves to 100 days. Every duration above 2400h in your repository fails on that day. It is worth knowing how many there are before then.
It reads a config file and flags every place that assumes a certificate lives longer than it now does: cert-manager duration and renewBefore, Terraform validity_period_hours, openssl -days, cfssl expiry, keytool -validity, ACME renewal crons, Prometheus expiry alerts, pinned fingerprints, and stale 398 or 825 day numbers in runbooks. Each finding carries the line number and the date the limit changes.
Platform and SRE engineers who own TLS renewal for a fleet: Kubernetes clusters running cert-manager, Terraform that issues ACM or self-signed certificates, certbot or acme.sh on servers, and the monitoring rules that alert on expiry. If you own the renewal pipeline and a certificate outage is your page, this is aimed at you.
A free checker inspects a certificate that has already been issued, so it tells you after the wrong config shipped. An AI assistant answers from training data: most still say the maximum is 398 days, or that Let's Encrypt is fixed at 90 days. Ballot SC-081v3 passed in April 2025 and took effect on 2026-03-15, and the schedule keeps moving.
Free checks any one open file against all 24 rules and shows every finding with its line number and severity - nothing is hidden or watermarked. A licence adds scale and repetition: the whole repository in one pass, a CI gate that fails the build, an exported CSV, JSON or HTML audit file, and in-place rewriting of the durations.
Hosted certificate monitoring runs about 17 to 19 US dollars every month - Better Stack Starter is 204 dollars a year for 20 domains, TrackSSL Starter is 19 dollars a month - and it watches certificates rather than the configuration that issues them. This is 29 dollars once.
One question, answered by the person who built it. Your email only if you want the answer sent.