Certificate Expiry: The Outage Everyone Has Once
There is a special category of outage that begins at an exact, predictable second. Not a disk filling up gradually, not a surprise attack — a timestamp, written inside a file on your own server, known years in advance to anyone who cared to look. And yet: the partner uploads that stop at midnight, the web file drop suddenly showing warnings to every visitor, the scheduled jobs erroring in unison. Ask any room of administrators who has had a certificate expire in production, and watch every hand go up.
This article is about making sure your hand goes up only once. The fix is not "be more careful" — careful people have this outage constantly, because the failure is organizational, not personal. The fix is a small system: an inventory that knows every certificate you depend on, monitoring that checks the live endpoints and warns while there is still slack, and a renewal runbook with named owners so the work lands on a person instead of on hope. All three are in this article, in copy-paste form. It is part of our Certificate Management series, and it leans on the installation and verification habits from installing certificates and getting the chain right.
Why the Most Predictable Outage Keeps Happening
Expiry outages persist for reasons worth naming, because each one points at a piece of the fix:
- The certificate outlives its context. It was installed by a contractor, or by the admin who left, or during a migration nobody documented. The expiry date is known to the file and to no living person. This is an inventory problem.
- The warning went somewhere dead. Many CAs email renewal reminders — to the address used at purchase, which is a departed employee or an unmonitored mailbox. Reminder email is marketing-grade reliability; production deserves better. This is a monitoring problem.
- Everyone owns it, so no one does. The certificate is "infrastructure," the renewal is "on the list," and lists without names are wishes. This is an ownership problem.
- Automation fails silently until it fails loudly. Unattended transfer clients do not click through warnings — they correctly refuse to connect, at 2 a.m., with no human present. The first report often comes from a partner, which is the most expensive way to learn. This is a verification problem.
- There are more renewals than there used to be. Modern public certificates have short lifetimes by design — short enough that manual, memory-based renewal is no longer a plausible strategy for even a modest estate. The industry's direction is clear: lifetimes shrink, automation becomes mandatory. Fighting that trend by trying harder is a losing plan.
Notice that none of these are cryptography problems. That is the good news: the whole fix is process, and small-team-sized process at that.
What Expiry Looks Like When It Lands
Recognizing the signature saves an hour of misdirected diagnosis. Expiry has three tells. First, simultaneity: every client fails at once, regardless of platform or network — because they all run the same date check against the same certificate. Second, the clean start time: the failures begin at the certificate's Not After instant, so logs show a hard edge, not a degradation. Third, the error family: browsers show expiry warnings, transfer clients log certificate has expired or a generic verification failure, and scheduled jobs stack up retry errors.
The duration of the outage, notice, is not set by the certificate — it is set by how long your renewal process takes when run under pressure. A team with a current inventory and a rehearsed runbook restores service in minutes: obtain or locate the renewed certificate, install, reload, verify. A team without them spends the same morning discovering who the CA even is, hunting for the private key, and learning chain assembly live. Everything in the rest of this article is about being the first team.
Remember it cuts both ways: your client jobs depend on other people's certificates too. When a partner's FTPS server certificate expires, your overnight transfers to them fail with the same signature — an unattended client such as Sysax FTP Automation validates the remote certificate on every scheduled run, so its job log is often where a partner's expiry first becomes visible on your side. The practical consequence: your monitoring list should include the remote endpoints your automation connects to, not just the servers you own.
Step One: Build the Certificate Inventory
You cannot monitor what you have not found, so the system starts with a census. Sources to sweep, in rough order of yield:
- Your transfer server configurations. Every FTPS and HTTPS service has a certificate bound to it — including the ones on the box everyone forgot. A server like Sysax Multi Server serving FTPS and HTTPS from one configured certificate is one inventory row; a box accumulated over years may surprise you with three.
- A listener scan of your own ranges. Probe your address space for TLS-speaking ports (web, implicit FTPS, admin interfaces) and harvest the certificates they present. This catches services running outside the official configuration records.
- DNS records. Names pointing at your infrastructure imply endpoints clients use; each name in use needs to appear in some certificate's SAN list, and each certificate found this way needs a row.
- Partner documentation. B2B flows add certificates you do not own but do depend on: partner server certificates your jobs validate, partner-held certificates that sign or encrypt payloads in protocols like AS2 — whose renewal requires coordination in both directions, as covered in AS2 certificate lifecycles.
- Internal CA issuance records. If you run a private CA, its log of issued certificates is an inventory feed — including the internal root itself, which also expires, spectacularly.
Record each certificate in a flat, boring, sortable format. A template to copy — a spreadsheet or a plain text file both work; the discipline matters, not the tooling:
CERTIFICATE INVENTORY — one row per certificate, reviewed quarterly endpoint / purpose port protocol names (SANs) issuer expires owner deputy renewal method last verified --------------------------------------------------------------------------------------------------------------------------------------------------------- files.example.com 443 HTTPS file drop files.example.com public CA yyyy-mm-dd J.Rivera D.Osei ACME + deploy hook yyyy-mm-dd ftp.example.com 21 FTPS (explicit) ftp,files.example.com public CA yyyy-mm-dd J.Rivera D.Osei runbook CERT-RB-01 yyyy-mm-dd ftp.example.com 990 FTPS (implicit) same cert as port 21 public CA yyyy-mm-dd J.Rivera D.Osei with port 21 renewal yyyy-mm-dd intranet.example.local 443 internal HTTPS intranet.example.local internal CA yyyy-mm-dd D.Osei J.Rivera internal CA reissue yyyy-mm-dd internal root CA - trust anchor Example Internal Root self yyyy-mm-dd D.Osei IT mgr root rotation plan yyyy-mm-dd partner-ftps.acme.example 21 FTPS (we connect) partner-owned partner's CA yyyy-mm-dd M.Chen J.Rivera request from partner yyyy-mm-dd
Three columns do the heavy lifting. Owner and deputy turn "someone should renew this" into "J. Rivera renews this, and D. Osei does when J. is on leave." Renewal method records how — automated, runbook, or ask-the-partner — so the knowledge survives turnover. Last verified is the honesty column: the date someone last confirmed, from outside, that the live endpoint serves the certificate the row describes.
Monitoring That Warns Early
With the inventory in hand, monitoring is a small loop with one crucial property: check the live endpoint, not the file on disk. A file check tells you a renewed certificate exists somewhere; only a live check proves the service is actually presenting it — which also catches the renewed-but-never-reloaded failure and the load balancer node serving a stale copy. The checking tool is the same handshake used for verification during installation:
# endpoints.txt — one line per check: host port [starttls-protocol]
# files.example.com 443
# ftp.example.com 21 ftp
# ftp.example.com 990
# partner-ftps.acme.example 21 ftp
while read host port tls; do
case "$tls" in
"") opts="" ;;
*) opts="-starttls $tls" ;;
esac
exp=$(echo | openssl s_client -connect "$host:$port" $opts \
-servername "$host" 2>/dev/null \
| openssl x509 -noout -enddate)
echo "$host:$port $exp"
done < endpoints.txt
Run it on a schedule, compare the dates against thresholds, and raise alerts. Sensible threshold tiers for a small team:
- First warning at about 30 days out — enough slack to renew calmly through any process, including a slow partner or an approval chain.
- Escalation at about 14 days — the renewal should be in progress; if the alert is still firing, something is stuck and a second person (the deputy) gets pulled in.
- Emergency at 7 days — treat like an incident-in-waiting: daily visibility until resolved, because the remaining slack no longer absorbs a vacation or a CA hiccup.
Route alerts to a team-visible place — a shared channel, a ticket queue — never to one person's inbox, which is a single point of failure with a vacation schedule. And monitor by name and port as clients use them: every SAN in use, every TLS port (explicit and implicit FTPS are separate checks), and the partner endpoints your jobs depend on. Uptime monitoring you already run may support certificate-age checks natively; use whatever fires reliably — the loop above is the fallback that works anywhere.
Then test the alarm itself, once, deliberately. Point the check at an endpoint you know sits inside the warning window (or temporarily lower a threshold) and confirm a human actually sees the alert land where you expect. Monitoring that has never fired is a hypothesis, not a safeguard. Finally, wire the inventory into your change habits: a new FTPS site, a new HTTPS listener, a new partner connection each add a row and a line in endpoints.txt on the day they are built — retrofitting discovery once a year is how shadow certificates are born.
Remember: the goal is not to remember better — it is to build a system in which forgetting is impossible. Inventory, live-endpoint monitoring, and a named owner per certificate together mean an expiry cannot arrive unannounced, no matter who is on leave, who has quit, or who is simply human.
The Renewal Runbook
An alert is only useful if it lands on a documented procedure. Renewal done ad hoc rediscovers the process each time, under time pressure, occasionally reinventing last year's mistake. A runbook makes the ninth renewal identical to the first. Copy and adapt:
RENEWAL RUNBOOK — ftp.example.com (serves FTPS 21/990 + HTTPS 443)
Owner: J. Rivera Deputy: D. Osei Inventory row: #2
Window: any weekday 07:00-09:00 (lowest transfer volume)
T-30d [owner] 30-day alert fires -> open ticket from this template.
T-28d [owner] Confirm renewal path unchanged (same CA, same SAN list).
If names changed since last cycle, update CSR first —
see the request walkthrough article.
T-21d [owner] Obtain new certificate: run request/validation, or
confirm the automated (ACME) renewal has produced it.
T-14d [owner] Install: assemble full chain (leaf + intermediates),
stage key + chain on the server, keep old cert in place.
T-14d [owner] If any partner pins or pre-registers our certificate:
send them the new certificate now, with the cutover date.
T-7d [owner] Apply configuration + reload service in the window.
T-7d [owner] VERIFY FROM OUTSIDE, every port and name:
echo | openssl s_client -connect ftp.example.com:21 \
-starttls ftp -servername ftp.example.com
-> full chain present, Verify return code: 0,
new dates served, SANs correct.
T-7d [owner] Confirm a real transfer succeeds (test account job).
T-6d [deputy] Independent spot-check from an external network.
T0 [owner] Old expiry date passes: confirm zero alerts, close
ticket, update inventory (new expiry, last verified).
Any [either] Escalate to deputy + manager if blocked > 3 days.
The design points, so you can adapt it honestly: every line has a name, not a role-shaped blank; the partner-notice step exists because some B2B clients validate or record your exact certificate and fail on unannounced changes; verification is external and per-port, because that is what caught the misinstalls in the installation article; and the runbook ends by updating the inventory, which is what keeps the system alive for the next cycle.
Automate What You Can, Calendar the Rest
For public-facing endpoints, the modern answer to renewal frequency is protocol-level automation — the ACME concept described in getting certificates, where an agent revalidates, fetches, and deploys certificates on a cycle with no human in the loop. Where it fits, use it; short-lifetime certificates all but require it. But automation changes the monitoring job rather than removing it: you now watch for the automation failing — an agent erroring quietly for weeks, a deploy hook that copies the file but never reloads the service. The live-endpoint check stays, precisely because it verifies the outcome and not the machinery. Trust the automation; verify the endpoint.
Some certificates resist automation structurally, and the calendar-plus-runbook system is their permanent home:
- Appliances and closed platforms that only accept a manually imported certificate.
- Partner-coordinated certificates — anything pinned, pre-registered, or exchanged out of band, where a renewal is a small bilateral project with notice periods.
- Client certificates issued to partners for mutual TLS, which expire like any other and strand a partner's automation when they do — their lifecycle is part of client certificates and mutual TLS.
- Internal CA anchors — intermediates and the root itself. Root expiry invalidates everything signed beneath it at once; the rotation plan belongs in the inventory years ahead.
A Note on Blame, and the Better Postmortem
When an expiry does land — and one eventually does; that is why this article's title says "once" — resist the instinct to find the person who forgot. The postmortem question is never "who forgot?" but "which part of the system was missing?" No inventory row? No live check on that port? Alert routed to a dead mailbox? Runbook without a deputy? Each answer converts an embarrassment into a permanent upgrade. Teams that blame build fear; teams that fix the system stop having this outage. The same posture serves you across the wider operational surface — the logging that would have shown the first failed handshake, for instance, is part of a discipline covered throughout our hardening transfer servers series.
The Version to Tell a Colleague
Certificate expiry is the most preventable outage in the catalog: the failure time is literally printed in the certificate. It keeps happening because prevention is organizational — so build the small system instead of trusting memory. One inventory with every certificate you serve or depend on, each row carrying an owner, a deputy, a renewal method, and an expiry date. One monitoring loop that checks the live endpoints — every name, every port, partners included — and warns at 30, 14, and 7 days into a team-visible channel. One runbook per certificate so renewal is a procedure, not an adventure, ending with external verification and an inventory update. Automate renewal wherever the endpoint allows it, and keep monitoring anyway, because automation fails too — just more quietly.
The neighboring skills complete the loop: installing and chaining covers the verification commands the runbook leans on, and getting certificates covers request-time decisions — including the automation planning that makes half of this article unnecessary for your public endpoints.
Frequently Asked Questions
How far in advance should I renew a certificate?
Why did every client fail at the same moment?
My certificate renews automatically. Do I still need monitoring?
Should I monitor certificates on servers I do not own?
What is the single most important field in the certificate inventory?
Can intermediate and root certificates expire too?
From the Sysax team: we build secure file transfer software for Windows — Sysax Multi Server, an FTP, FTPS, SFTP, and HTTPS server, and Sysax FTP Automation for scheduled, scripted transfers. Free trials are on the download page.
