BlogSecurity · Monitoring
MonitoringTLSDevOpsSecurity

Certificate Expiry Monitoring — A Practical Guide

Certificates expire. It is not a question of if — only when. An expired certificate causes immediate, complete service outages. This guide covers how to monitor certificate expiry proactively so you never get caught out.

Navsatech Team·March 2026·5 min read

Why certificates expire in production

You might wonder — if engineers know certificates expire, why do they still expire in production? The answer is always the same: the person who installed the certificate is not the same person responsible for renewing it, or the renewal process was manual and got missed during a busy release cycle.

01
No monitoring in place
The most common cause. Nobody is watching the expiry date. The certificate expires overnight and the service breaks at 2am.
02
Renewal reminder sent to a shared inbox nobody reads
CA renewal reminders go to a generic email address that's unmonitored, or to an engineer who has since left the company.
03
Certificate renewed but not deployed
The new certificate was obtained but the deployment step was missed or forgotten. The old expired certificate stays in place.
04
Internal / private CA with short validity
Internal CAs often issue certificates with 1-year or even 90-day validity. These are easy to miss without active monitoring.

Alert thresholds that actually work

A single "expires in 30 days" alert is not enough. Alerts get missed, go to the wrong person, or arrive during a holiday. Use a staged alert strategy:

📅
60 days — First notice
Enough time to go through any approval processes, generate a new CSR, get it signed, and test in staging before production deployment.
⚠️
30 days — Action required
Renewal should be in progress or completed. If not, escalate immediately.
🔴
7 days — Critical
Immediate action required. Page on-call if renewal is not already deployed.
💀
0 days — Expired
Service is broken or will break imminently. Emergency response required.

Manual expiry checks

Check a live domain's certificate expiry:

echo | openssl s_client -servername example.com \
  -connect example.com:443 2>/dev/null \
  | openssl x509 -noout -dates

Check a local certificate file:

openssl x509 -in cert.pem -noout -dates

Check all certificates in a JKS keystore:

keytool -list -v -keystore keystore.jks -storepass changeit \
  | grep -E "Alias|Valid from|until"

Script to check multiple domains:

#!/bin/bash
DOMAINS=("example.com" "api.example.com" "internal.company.com")
WARNING_DAYS=30

for domain in "${DOMAINS[@]}"; do
  expiry=$(echo | openssl s_client -servername $domain \
    -connect $domain:443 2>/dev/null \
    | openssl x509 -noout -enddate 2>/dev/null \
    | cut -d= -f2)
  expiry_epoch=$(date -d "$expiry" +%s 2>/dev/null || date -j -f "%b %d %T %Y %Z" "$expiry" +%s)
  now_epoch=$(date +%s)
  days_left=$(( ($expiry_epoch - $now_epoch) / 86400 ))
  echo "$domain: $days_left days remaining (expires $expiry)"
done

Automated monitoring approaches

Prometheus + Blackbox Exporter — if you're already running Prometheus, the Blackbox Exporter has a built-in SSL certificate expiry probe. Add an alert rule:

- alert: SSLCertExpiringSoon
  expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 30
  for: 1h
  labels:
    severity: warning
  annotations:
    summary: "SSL cert expiring in less than 30 days — {{ $labels.instance }}"

Nagios / Icinga — use the check_http plugin with the --ssl and --certificate flags to alert on expiry.

Cron-based script — run the shell script above daily via cron and send results to Slack or email.

Using CertLens Monitor

CertLens has a built-in certificate monitor that scans your domains on a schedule and alerts you before certificates expire — no setup beyond adding your domain.

Free certificate expiry monitoring
Add any domain to CertLens Monitor. It scans on your chosen schedule (every 6, 12, or 24 hours), tracks expiry, and generates alerts at 60, 30, and 7 days — with a full scan history for each domain.
Set Up Monitoring →
✓ Configurable scan interval
✓ 60/30/7 day alerts
✓ Full scan history
✓ Risk level tracking

CI/CD pipeline checks

Add a certificate check to your deployment pipeline so an expiring certificate blocks the release and forces a renewal:

#!/bin/bash
# check-cert-expiry.sh — add to CI pipeline
DOMAIN="$1"
MIN_DAYS="${2:-30}"

expiry=$(echo | openssl s_client -servername $DOMAIN \
  -connect $DOMAIN:443 2>/dev/null \
  | openssl x509 -noout -checkend $(($MIN_DAYS * 86400)))

if [ $? -ne 0 ]; then
  echo "ERROR: Certificate for $DOMAIN expires within $MIN_DAYS days. Renew before deploying."
  exit 1
fi
echo "OK: Certificate for $DOMAIN is valid for more than $MIN_DAYS days."

Add to your GitHub Actions workflow:

- name: Check certificate expiry
  run: ./check-cert-expiry.sh api.example.com 30
Copilot
CertLens Copilot
AI-powered PKI assistant
Hi! I'm CertLens Copilot — ask me anything about certificates, TLS errors, JKS keystores, SWIFT PKI, or trust chain issues.