ZeroSSL 90-Day Certificate Renewal SOP: 5 Steps to Never Lose Your HTTPS
Last article (8/29 W6) I installed ZeroSSL on my baccarat PRO tool, promising "I'll write the 90-day renewal SOP separately". Here it is. It's Sep 4, 83 days left until the 8/27 cert expires. I've dry-run the full SOP on a staging domain and codified the 5 steps.
For anyone in the same situation: self-hosted tool + installed ZeroSSL + don't want ACME agent + willing to spend 5 min per quarter doing it manually.
1Reminder email 14 days before expiry
ZeroSSL sends a reminder email 14 days before your cert expires (to the address used during application). Filter zerossl@yourdomain.com in Gmail/Resend to never miss it.
Email looks like:
Subject: [ZeroSSL] Your certificate for www.baccpc.com will expire in 14 days
The certificate for www.baccpc.com issued on 2026-08-27
will expire on 2026-11-25 (in 14 days).
To renew: https://app.zerossl.com/certificate/xxxxxx/renew
Don't click the email link (it's legit, but going to app.zerossl.com directly is more reliable).
2ZeroSSL reissue: 5 seconds
- Login at app.zerossl.com
- Left nav Certificates → find www.baccpc.com (Expiring in 14 days)
- Click "Renew Certificate"
- Modal: "Choose a verification method" → select DNS CNAME (same as initial; HTTP not viable since port 80 is IIS)
- Next → ZeroSSL generates new CNAME (hash will change!)
Pitfall #1: The renewal CNAME hash is completely different from the initial one. Must delete old + add new CNAME, not just edit the value.
3GoDaddy DNS: delete old + add new CNAME (10 min)
- Login at dcc.godaddy.com → My Products → Domains → baccpc.com → DNS → Records
- Find
_5CA856F20F2D109CF6B26F0927B1A43C.baccpc.comCNAME → Delete - Add → Type CNAME → Host
_A8F7BC2D3E1F4A5B6C7D8E9F0A1B2C3D→ Value9f7b11cfa5af85172870e15936857fb9.4a282cda8c9d892096197e0833bf72a0.ab12883837f650a.comodoca.com→ TTL 600 → Save - Wait 5-10 min, verify with
nslookup -type=cname _A8F7BC2D3E1F4A5B6C7D8E9F0A1B2C3D.baccpc.com
Back in ZeroSSL → see green "Verified" → "Download Certificate" → grab certificate.crt + ca_bundle.crt.
4Flask server: replace cert.pem + restart (3 min)
Use the Python cryptography script from my W6 SSL install article to merge leaf + chain into cert.pem with strict LF, copy to D:\phd824\:
# PowerShell 5.1: extract zip + run patch script
python _patch_old_pro_https_8_27.py
# Auto: backup cert.pem -> cert.pem.bak_8_27
# merge leaf + chain -> cert.pem (LF)
# verify cert + key public key match (cryptography)
# kill Python processes
# start Flask + wait 8s + netstat 8000/8443
Or manual: Get-Process python | Stop-Process -Force → restart python app.py → netstat | findstr 8443.
Pitfall #2: Flask doesn't auto-reload cert.pem. Must kill + restart. 5-10s downtime, users don't notice.
5Verify: HTTPS unbroken (1 min)
- Open
https://www.baccpc.com:8443/(PHD) → click cert info → should show new 90-day validity - Open
https://www.baccpc.com:8000/(old PRO) → same - Mobile 4G/5G spot check, green padlock present
Total flow: 5 minutes (excluding 10 min DNS propagation wait).
Fig 1: Renewal 5-step checklist (email → reissue → DNS → replace → verify)
Annual renewal calendar: 4 actions, 4 dates
| Issue date | Renewal action (T-14 days) | New cert active | Cert expires |
|---|---|---|---|
| 2026-08-27 | 2026-11-11 (Tue) | 2026-11-12 | 2026-11-25 |
| 2026-11-25 | 2027-02-10 (Wed) | 2027-02-11 | 2027-02-23 |
| 2027-02-23 | 2027-05-11 (Tue) | 2027-05-12 | 2027-05-24 |
| 2027-05-24 | 2027-08-10 (Tue) | 2027-08-11 | 2027-08-22 |
Add those 4 action dates to your calendar with title "🔒 HTTPS Renewal" + repeat reminder 7 days before each.
Why not ACME auto-renewal?
- Complexity: ACME agent (acme.sh / certbot) install + DNS API token + cron + failure alerts. ~30 min setup, 1 hr/yr maintenance
- Risk: Auto-renewal fails more often than expected (DNS API changes / cron skipped / file perms), usually at midnight, users see red locks
- Cost: 4 manual renewals × 5 min = 20 min/yr, comparable to automation overhead, with log review built-in
Pick manual + calendar for single domain. Use ACME for 10+ domains / company scale.
Pitfall checklist (saves 30 min)
- Renewal CNAME hash changes → must delete old + add new, not just edit value
- Flask doesn't auto-reload cert → must kill + restart
- DNS not propagated yet → wait 5 min, then nslookup
- PowerShell merge introduces CRLF → use Python cryptography with strict LF
- Forgot expiry date → set 3 reminders (T-14 email + T-7 calendar + T-1 calendar)
Each is real, not from docs. All from W6 install + W7 dry-run on staging.
Fig 2: 90-day renewal cycle (issue → T-14 reminder → renew → new cert active → expire)
Takeaway: HTTPS renewal is not that complex, don't be scared by automation
ZeroSSL 90-day renewal = 5 steps + 5 min + 4 times/yr. Add calendar reminder, total time investment 25 min/yr. ACME automation might save 5 min, but adds ops complexity + failure risk.
Next week I'll write "How HTTPS encryption works: 5 minutes for non-technical readers" - same SSL theme, different angle (science/edu vs tool/SOP). Reply if you want IIS ARR reverse proxy setup (terminate 80/443 TLS at IIS, Flask only runs 8000 internal).
Want the W6 6-hour install log? See PRO Tool SSL Install Log.