How to Track SSL Certificate Expiry Dates in Bulk

Manage SSL certificate expiry dates across dozens or hundreds of certificates. Methods from scripts to dedicated monitoring tools for teams of every size.

One certificate is easy to track. You know the domain, you know when it expires, you renew it when the time comes. But nobody manages just one certificate. You've got the main site, the API, staging environments, client microsites, internal tools, mail servers, and that legacy app nobody wants to touch. Across different servers, different CAs, and different teams. When you have 20, 50, or 200 certificates, manual tracking isn't just inefficient -- it's a guarantee that something will expire without warning.

The Scaling Problem

Certificate management doesn't scale linearly. Every certificate you add creates multiple tracking obligations:

  • Expiry dates spread across different renewal windows (90 days for Let's Encrypt, 1 year for commercial certs)
  • Multiple CAs with different portals, different renewal flows, and different validation requirements
  • Multiple servers where the same certificate might be installed (web server, load balancer, CDN, reverse proxy)
  • Multiple teams where no single person knows about every certificate
  • Shadow certificates that someone deployed six months ago and nobody documented

At 5 certificates, you can keep this in your head. At 20, you need a system. At 50+, anything short of automated monitoring is a liability.

Method 1: The Spreadsheet

The simplest approach. A shared spreadsheet (Google Sheets, Excel) with columns for domain, issuer, expiry date, server location, and renewal owner.

Pros

Free, familiar, no tooling required. Works for small teams with few certificates. Easy to share and annotate.

Cons

Requires manual updates. Data goes stale immediately. No alerts. Relies on someone remembering to check it. Doesn't verify actual certificate state -- just records what someone typed in.

Breaks at: 15-20 certificates. Once you're past that, someone will forget to update the sheet after a renewal, the dates will drift from reality, and you'll be back to surprised-by-expiry territory.

A spreadsheet is better than nothing. But it's a documentation tool, not a monitoring tool. It records what you believe to be true, not what is actually true.

Method 2: Shell Script with OpenSSL

For the engineering-minded, a bash script that checks certificates in a loop is a big step up from a spreadsheet.

#!/bin/bash
# check-certs.sh - Check SSL certificate expiry for a list of domains

DOMAINS=(
  "example.com"
  "www.example.com"
  "api.example.com"
  "staging.example.com"
  "app.example.com"
)

WARN_DAYS=30
WARN_SECONDS=$((WARN_DAYS * 86400))

for domain in "${DOMAINS[@]}"; do
  expiry=$(openssl s_client -connect "$domain:443" -servername "$domain" </dev/null 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)

  if [ -z "$expiry" ]; then
    echo "ERROR: Could not connect to $domain"
    continue
  fi

  expiry_epoch=$(date -d "$expiry" +%s 2>/dev/null || date -j -f "%b %d %T %Y %Z" "$expiry" +%s 2>/dev/null)
  now_epoch=$(date +%s)
  days_left=$(( (expiry_epoch - now_epoch) / 86400 ))

  if [ "$days_left" -lt 0 ]; then
    echo "EXPIRED: $domain expired $((days_left * -1)) days ago ($expiry)"
  elif [ "$days_left" -lt "$WARN_DAYS" ]; then
    echo "WARNING: $domain expires in $days_left days ($expiry)"
  else
    echo "OK: $domain expires in $days_left days ($expiry)"
  fi
done

Run this via cron daily and pipe the output to email or a Slack webhook.

Pros

Actually checks live certificates (not just what's recorded). Free. Customizable. Can integrate with alerting systems.

Cons

You have to maintain the script. The domain list is manual. Doesn't check certificate chain or configuration quality. Breaks when servers block connections or use non-standard ports. No dashboard or history.

Breaks at: 30-50 certificates. Script maintenance becomes a job in itself. Adding new domains requires editing the script. Error handling for edge cases (timeouts, SNI issues, non-standard ports) grows the script beyond what anyone wants to maintain. And when the cron server itself has issues, nobody gets alerts about anything.

Method 3: Infrastructure Monitoring Plugins (Nagios, Zabbix, Prometheus)

If you already run infrastructure monitoring, SSL certificate checks can be added as plugins or exporters.

Nagios: The check_ssl_cert plugin monitors certificate expiry and chain validity. Configure it as a service check for each domain.

Zabbix: Built-in web scenarios and the zabbix-ssl-check template can monitor certificate expiry. Integrates with Zabbix's alerting system.

Prometheus: The ssl_exporter or blackbox_exporter with the tls prober scrapes certificate metrics (expiry timestamp, chain length, issuer). Pair with Grafana dashboards and Alertmanager for notifications.

# Prometheus blackbox_exporter config for SSL checks
modules:
  tls_connect:
    prober: tcp
    tcp:
      tls: true
      tls_config:
        insecure_skip_verify: false

Pros

Integrates with your existing monitoring stack. Sophisticated alerting (escalation, on-call rotation). Historical data and dashboards. Free/open-source.

Cons

Requires running and maintaining monitoring infrastructure. Setup is non-trivial. Not purpose-built for SSL -- it's one check among thousands. Overkill if you don't already run Nagios/Zabbix/Prometheus.

Breaks at: It doesn't really break at scale -- these tools handle thousands of checks. But the overhead of maintaining the monitoring infrastructure itself is significant. If you're setting up Prometheus just for SSL checks, you're using a sledgehammer to hang a picture frame.

Skip the infrastructure overhead

Purpose-built SSL monitoring. Add domains, get alerts. No servers to maintain.

Method 4: Dedicated SSL Monitoring Tools

Purpose-built SSL monitoring tools are designed specifically for tracking certificate expiry across many domains. They handle the problems that scripts and spreadsheets can't.

What a good SSL monitoring tool provides:

Automatic certificate discovery

Add a domain and the tool extracts all certificate details automatically -- expiry date, issuer, SANs, chain status.

Escalating alerts

Notifications at multiple intervals before expiry (30, 14, 7, 3, 1 day). If the first alert is missed, subsequent ones get louder.

Multi-channel notifications

Email, Slack, webhooks, PagerDuty -- alerts go where your team actually sees them.

Dashboard with sorting and filtering

See all certificates sorted by expiry date. Filter by issuer, status, or team. Spot problems at a glance.

Chain and configuration validation

Not just expiry -- checks that the chain is complete, protocols are secure, and the certificate is correctly installed.

No infrastructure to maintain

SaaS tools run on their own infrastructure. Nothing to install, patch, or keep alive on your servers.

Comparing the Approaches

ApproachCostSetup TimeAuto-AlertsChain ChecksScales To
SpreadsheetFreeMinutesNoNo~15 certs
Shell script + cronFreeHoursBasic (email)No~50 certs
Nagios/Zabbix/PrometheusFree (self-hosted)DaysYesYes (with plugins)Thousands
Dedicated SSL monitoringFree-$9/moMinutesYes (escalating)YesUnlimited

What to Look For in a Bulk SSL Tracking Solution

If you're evaluating tools, here's what matters for bulk certificate management:

Must-haves:

  • Easy bulk import (paste a list of domains, not one-by-one entry)
  • Expiry-sorted dashboard (the certificate expiring soonest should be at the top)
  • Configurable alert thresholds (30, 14, 7 days -- not a fixed single warning)
  • Team notification channels (not just the person who set it up)
  • Chain validation (catch missing intermediates, not just expired leaves)

Nice-to-haves:

  • Certificate change detection (alert when a certificate is replaced unexpectedly)
  • Historical tracking (see when certificates were renewed, who changed what)
  • API access (integrate with your deployment pipeline)
  • Tag/group management (organize certificates by team, environment, or project)

The Real Cost of Not Tracking

When a certificate expires unexpectedly on a production site:

  • Revenue loss: E-commerce sites lose every transaction during the outage. Visitors see "Your connection is not private" and leave.
  • SEO impact: Google deindexes pages that return SSL errors. Recovery takes days or weeks.
  • Trust damage: Customers who see a security warning may not come back, even after the issue is fixed.
  • Engineering cost: Emergency renewals at 2 AM involve the most expensive, least productive engineering hours.

The cost of any tracking solution -- even the most expensive one -- is trivial compared to a single certificate expiry incident. The question isn't whether you can afford monitoring. It's whether you can afford not having it.

Pick the approach that matches your scale. If you have 5 certificates and one server, a cron script is fine. If you have 50 certificates across multiple teams and environments, invest in a proper monitoring tool. Either way, have something -- because the spreadsheet you never update is the same as having nothing at all.


One expired certificate is an incident. Two is a pattern. Three is a missing process.

Never miss an SSL certificate expiry

Monitor your certificates and get alerts before they expire. Free for up to 3 certificates.