Cloudflare is widely used precisely because it handles SSL termination automatically: Universal SSL certificates are provisioned and renewed without any action from you. So does that mean SSL certificate monitoring is a solved problem if you're on Cloudflare?
Not quite. The gap is narrower than it is with raw servers, but the scenarios where Cloudflare's automatic handling breaks down or doesn't apply are exactly the scenarios that tend to cause outages.
Cloudflare's Universal SSL covers the edge certificate — the one visitors see when they connect to your domain through Cloudflare's proxy. Cloudflare handles:
example.com and *.example.com)For most public web traffic, this works without any configuration changes.
Cloudflare terminates SSL at the edge, but traffic between Cloudflare and your origin server is separate. If you're using Full (strict) SSL mode — the recommended setting — your origin server needs a valid certificate too.
You can use a Cloudflare Origin Certificate (valid for up to 15 years) or a Let's Encrypt cert on your server. Cloudflare Origin Certificates have long validity windows but are not trusted by browsers directly — they're only valid for Cloudflare-to-origin traffic. If someone accesses your server IP directly or Cloudflare is temporarily disabled, the connection fails.
Regardless of which origin cert you use, you should monitor its expiry date. The Cloudflare dashboard doesn't surface your origin cert expiry — you need an external check.
If you've uploaded a custom SSL certificate to Cloudflare — common for compliance requirements, internal PKI, or certificates from specific CAs — automatic renewal doesn't apply. Cloudflare will show a warning in the dashboard when these approach expiry, but a passive dashboard warning is not the same as a timely alert to your inbox.
Cloudflare's Universal SSL only protects traffic routed through the Cloudflare proxy (the orange cloud in the DNS dashboard). If a record is set to DNS-only (grey cloud), Cloudflare is purely a DNS resolver — your origin server handles SSL directly. The certificate on that server is entirely your responsibility.
This catches teams off-guard: a domain moved to DNS-only for testing, an API subdomain that bypasses the proxy for latency reasons, a mail server pointing at a different IP. All of these have no Cloudflare SSL coverage.
*.example.comUniversal SSL covers one subdomain level. If you have deep subdomains like app.internal.example.com, they're not covered by Cloudflare's automatic cert. You'd need an Advanced Certificate Manager subscription and explicit wildcard coverage configuration — and those custom certs have renewal workflows you need to manage.
If you're using Cloudflare Tunnel, Workers, or API endpoints that present their own certificates, expiry monitoring still applies to those endpoints separately.
The standard openssl s_client approach works here, but with a nuance: when a domain is proxied through Cloudflare, you're seeing Cloudflare's edge certificate — not your origin cert. To check the origin cert specifically, you need to connect directly to your origin server IP and bypass Cloudflare.
Check the edge cert (what visitors see):
echo | openssl s_client -servername yourdomain.com \
-connect yourdomain.com:443 2>/dev/null \
| openssl x509 -noout -enddate
Check your origin cert directly (replace ORIGIN_IP with your server's IP):
echo | openssl s_client -servername yourdomain.com \
-connect ORIGIN_IP:443 2>/dev/null \
| openssl x509 -noout -enddate
For a quick view of days remaining:
#!/bin/bash
DOMAIN="yourdomain.com"
EXPIRY=$(echo | openssl s_client -servername "$DOMAIN" \
-connect "$DOMAIN:443" 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s 2>/dev/null \
|| date -j -f "%b %d %T %Y %Z" "$EXPIRY" +%s)
DAYS_LEFT=$(( (EXPIRY_EPOCH - $(date +%s)) / 86400 ))
echo "$DOMAIN: $DAYS_LEFT days remaining (expires $EXPIRY)"
Cloudflare's API exposes certificate details for custom certificates and advanced certs. If you're managing multiple zones:
# List SSL certificates for a zone
curl -s -X GET \
"https://api.cloudflare.com/client/v4/zones/ZONE_ID/ssl/certificate_packs" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
| python3 -m json.tool | grep -E "expires_on|status|type"
The expires_on field in the response gives you the expiry date for each certificate pack. You can automate this into a monitoring script that fires an alert when any cert is within 30 days of expiry.
Zone:SSL and Certificates:Read permission. Create a restricted token rather than using your global API key.
If you're managing several Cloudflare zones, a practical setup combines two checks:
| Cert type | Cloudflare manages renewal? | Monitoring approach |
|---|---|---|
| Universal SSL (edge) | Yes (automatic) | External HTTP check as backup |
| Origin certificate | No | External check on origin IP, or openssl cron |
| Custom / uploaded cert | No | Cloudflare API check + external HTTP check |
| DNS-only domains | No (not proxied) | External HTTP check on domain directly |
| Advanced Certificate Manager | Partial | Cloudflare API check for custom wildcards |
Before setting up automated monitoring, you can check any Cloudflare-proxied domain's certificate expiry immediately — no account login required:
Enter any domain to see days remaining, expiry date, and issuer. Works for Cloudflare-proxied domains and origin servers alike.
Check SSL expiry → Get expiry alerts →Manual checks are fine for a one-time audit. Automated monitoring means you get notified at 30, 14, 7, and 1 day before any certificate expires — including origin certs and custom certs that Cloudflare doesn't renew automatically.
The options range from a self-hosted cron script (fragile, maintenance overhead) to dedicated SSL monitoring tools that run external checks on a schedule. The key requirements for a Cloudflare-specific setup:
SSLWatch monitors SSL certificates externally and sends email alerts at 30, 14, 7, and 1 day before expiry. Works for Cloudflare-proxied domains, DNS-only records, origin servers, and any public HTTPS endpoint.
Join the SSLWatch waitlist → Free SSL checker →