We put six-day TLS certificates on production HAProxy. The restart was the real test.
Let’s Encrypt now offers a certificate that lasts 160 hours. We selected the shortlived
ACME profile for the main CertLocker edge, rolled it across two HAProxy nodes, and watched the same leaf
go live on both. Then a routine restart showed us the difference between “renewed” and
“survives the whole production lifecycle”.
The reason for doing this was not complicated. The profile exists, our platform supports it, and we wanted to run the awkward version of certificate automation on our own production edge. Why not? If we are telling other infrastructure teams that shorter lifetimes are manageable, our main HAProxy pair should be one of the places proving it.
That does not mean every team should switch to six-day certificates tomorrow. It means teams building certificate automation should understand what changes when a certificate is no longer something you can forget about for a quarter.
What Let’s Encrypt actually changed
Let’s Encrypt made short-lived certificates generally available on January 15, 2026. They are valid for
160 hours, just over six days, and are requested by selecting the
shortlived certificate profile in an ACME client. The normal 90-day certificate remains the default.
The important bit is that six-day certificates are an option, not the same thing as the wider industry move to shorter defaults. Let’s Encrypt’s current lifetime guidance says industry rules will cap certificates at 47 days from March 15, 2029, and that Let’s Encrypt plans to reduce its own maximum lifetime to 45 days by February 2028.
So yes, this puts us ahead of the 45-day change. But the useful part is not being early for the sake of it. A 160-hour certificate makes weak automation visible quickly. A stale token, a renewal that only exists in memory, a broken reload hook, or a probe that checks inventory instead of the live socket cannot hide for two months.
The production path we changed
Our public edge is a two-node HAProxy setup. Cloudflare sits in front, but each origin node still needs a coherent
certificate for certlocker.io and *.certlocker.io. The certificate path is HAProxy 3.3
native ACME talking to the CertLocker gateway:
The durable Ansible inventory records the non-secret parts:
certlocker_ha_haproxy_acme_directory: https://trust.certlocker.io/rest/acme/directory
certlocker_ha_haproxy_acme_domains: 'certlocker.io,*.certlocker.io'
certlocker_ha_haproxy_require_seeded_key: '1' The rendered HAProxy ACME section keeps the account key on a persistent volume and reuses the certificate key:
acme certlocker
directory https://trust.certlocker.io/rest/acme/directory
account-key /usr/local/etc/haproxy/certs/acme.account.key
challenge http-01
keytype ECDSA
bits 256
reuse-key on
The contact value is a scoped CertLocker token and is deliberately excluded here. Ansible resolves it from a named
secret, writes it into the runtime environment with no_log: true, and recreates only HAProxy. The PEM
seed is validated before use by comparing the public key from the private key with the public key in the leaf.
There was no full-stack deployment for the profile change. We used the narrow HAProxy partial, one node at a time. That matters. Certificate automation is exactly the wrong reason to restart a database, gateway, UI, or monitoring stack.
Node 2 first, then node 1
The first run targeted the secondary node only. Node 1 kept serving the previous certificate while node 2 recreated HAProxy, completed one native ACME update, and presented the new leaf. We checked the container, watchdog, origin routes, public routes, certificate names, key match, and fingerprint before touching the primary.
The second run repeated the same partial on node 1. At the end, both nodes served the same Let’s Encrypt YE2 certificate:
- Valid from August 17, 2026 at 12:35:39 UTC.
- Valid until August 24, 2026 at 04:35:38 UTC.
- Exactly two SAN entries:
certlocker.ioand*.certlocker.io. - The same SHA-256 fingerprint on both origins.
- The same seeded certificate-key public hash on both origins.
- Healthy HAProxy containers, zero restarts, active watchdogs, and HTTP 200 on the checked routes.
That is the proof we wanted. Not “the order says complete”. Not “the certificate exists in the inventory”. The leaf actually presented over TLS on both origins was the new 160-hour certificate.
The renewal window is deliberately uncomfortable
HAProxy’s Runtime API reported the certificate in Scheduled state. For this 160-hour leaf, its
automatic renewal point was August 23 at 15:15:39 UTC, roughly 13 hours 20 minutes before expiry.
That sounds tight if your mental model is a ticket raised 30 days before expiry. It is normal if issuance and delivery are runtime operations. The system has to obtain the certificate, load it, present it, and prove the endpoint is serving it without waiting for a person.
It also means the failure budget is honest. With a 90-day certificate, a broken renewal can sit unnoticed for weeks. With a 160-hour certificate, the retry policy, alert, token lifetime, CA availability, reload behavior, and live probe all become part of the same operating model.
Then we restarted HAProxy
Two days after the successful rollout, a normal application release recreated parts of the app tier. HAProxy itself had not changed, but it was restarted to refresh backend addresses. Public traffic remained healthy through Cloudflare. Both HAProxy containers came back healthy. A shallow check would have stopped there.
The origin certificate check found two separate gaps:
- The short-lived leaf had been updated in HAProxy’s runtime certificate store, but the newer bundle had not been persisted back to the mounted PEM. The restart loaded the older on-disk leaf.
- The ACME contact token left in the runtime environment was no longer active, so the startup renewal could not immediately repair the state.
This is the bit that matters most in the whole exercise. We had proved issuance. We had proved a rolling rollout. We had proved that both running processes served the six-day certificate. We had not yet proved that the result survived an unrelated container restart with current credentials.
That does not make the six-day test a failure. It makes it useful. The short lifetime forced us to look at the lifecycle as a complete system instead of treating one successful ACME order as the finish line.
Our revised definition of done
A short-lived certificate rollout is complete only when all of these are true:
- The issuer advertises the intended profile and the workflow records
shortlived. - The requested identifiers are exact. For us, that is the apex plus wildcard, not wildcard alone.
- The private key used by the ACME CSR matches the returned leaf.
- Every HA node presents the same expected fingerprint over a direct SNI connection.
- The ACME runtime reports a scheduled renewal time with enough retry runway.
- The current token remains usable for automatic renewal and restart recovery.
- The renewed bundle is persisted, not held only in process memory.
- A cold container restart still presents the expected leaf without manual intervention.
- Endpoint probes verify what production is actually serving.
- Renewal failure alerts reach someone before the remaining hours become an incident.
The direct HAProxy Runtime API command is useful, but it is only one check:
echo 'acme status' \
| docker exec -i certlocker-haproxy \
socat stdio /var/run/haproxy/admin.sock
openssl s_client -connect origin.example:443 \
-servername certlocker.io </dev/null 2>/dev/null \
| openssl x509 -noout -issuer -serial -dates \
-ext subjectAltName -fingerprint -sha256 The first command tells you what HAProxy thinks it manages. The second tells you what a client is actually being shown. You need both, plus a restart test.
What CertLocker makes easier
Selecting a six-day profile is the small part. The useful platform work is keeping the surrounding objects and evidence together:
- ACME clients discover and display the profiles supported by each issuer.
- Workflows keep the selected profile attached to the order.
- Certificate inventory records the issued leaf, identifiers, issuer, and validity window.
- Scoped tokens and stored secrets give automation a controlled path to what it needs.
- Audit events show profile changes, orders, certificate updates, and access.
- Endpoint probes check the certificate a service is actually presenting.
- Ansible can resolve named values without putting tokens or private keys in the repository or command output.
That is what makes shorter lifetimes realistic. Not a promise that renewal can never fail. A system that makes the workflow visible, keeps credentials scoped, detects drift, and gives you enough evidence to fix the real failure.
Should you use the six-day profile?
Use it where automation is already the normal path and where you can verify the live endpoint. It is a good fit for an edge you control, repeatable platform workloads, and teams deliberately testing their certificate delivery model ahead of shorter industry lifetimes.
Do not use it to create urgency around a manual process. Compared with a 90-day certificate, a 160-hour certificate creates roughly 13.5 times as many issuance events. If renewals depend on somebody copying a PEM, opening a change ticket, or remembering which HAProxy node is active, the profile will expose that process very quickly.
Start with one real service. Record the profile. Roll secondary first. Compare fingerprints. Restart it. Break the token in a controlled environment. Watch the alert. Confirm the probe. Then decide whether the shorter lifetime is buying you something useful.
Ahead of the curve means finding the boring failures early
We did get a six-day certificate onto both production HAProxy nodes. The same leaf was live, the rolling update was clean, and HAProxy scheduled the next renewal. CertLocker made the profile, workflow, secret lookup, audit trail, and deployment path manageable.
The restart then found the part that was not yet managed well enough. That is the real result. Being ahead of the 45-day curve is not a badge. It is having time to find persistence, token rotation, and verification gaps while they are engineering work, not an expiry incident.
Test the workflow, not just the order
Use the hosted evaluation for a quick look at ACME profiles, workflows, certificates, probes, and audit events. If you want to prove renewal and restart behavior against your own HAProxy, Nginx, IIS, or mixed estate, run a one-month onsite evaluation in the real environment.