← Blog  ·  October 2026

Monitoring SSL Certificates Across Multiple Domains: A Practical Guide

Managing three SSL certs is easy. Managing thirty is where things go wrong at 2am on a Saturday.

Most developers start with a single domain. One Let's Encrypt certificate, one auto-renewal cron job, and everything works. Then the portfolio grows: staging environments, client projects, acquired domains, subdomains for marketing campaigns. Suddenly you have fifteen SSL certificates from three different providers on four different servers, and no single place to see when any of them expire.

This guide covers the practical options for bulk SSL certificate monitoring — from manual shell scripts to automated monitoring — and where each approach breaks down as scale increases.


The problem with monitoring SSL certificates at scale

SSL certificates have a surprisingly short lifespan. Let's Encrypt certificates expire every 90 days, which means auto-renewal needs to run successfully eight times per year per domain — and fail silently the one time it matters most. Commercial certificates typically last one or two years, long enough to forget you configured them.

The failure modes that catch multi-domain operators off guard:


The manual approach: an openssl loop script

For small numbers of domains, a bash script that loops through a list is a reasonable starting point. Here's a functional version:

#!/bin/bash
# check-multi-ssl.sh — check expiry for multiple domains

DOMAINS=(
  "example.com"
  "api.example.com"
  "staging.example.com"
  "client-one.com"
  "client-two.net"
)
WARN_DAYS=30

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

  if [ -z "$EXPIRY" ]; then
    echo "FAIL  $DOMAIN (could not retrieve certificate)"
    continue
  fi

  EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s 2>/dev/null)
  NOW_EPOCH=$(date +%s)
  DAYS=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))

  if [ "$DAYS" -le "$WARN_DAYS" ]; then
    echo "WARN  $DOMAIN — expires in $DAYS days ($EXPIRY)"
  else
    echo "OK    $DOMAIN — expires in $DAYS days"
  fi
done

Run this daily via cron and pipe the output to a log file or email. For 5–10 domains, this works. For 30+, it becomes unwieldy.

The connection timeout problem openssl s_client doesn't have a built-in timeout flag on all platforms. For unreachable domains, the script hangs indefinitely. Add timeout 10 before the openssl command on Linux: timeout 10 openssl s_client .... Otherwise a single unreachable domain stalls the entire loop.

Where the shell script approach breaks down

No persistent state between runs

A script that runs daily either emails you every day for the last 30 days before expiry, or emails you only on the first day of the warning window. Neither is ideal. A proper monitoring system tracks state: it knows you've already been notified and sends escalating alerts (30 days out, 14 days out, 7 days out, 1 day out) without flooding your inbox.

No dashboard visibility

A loop script produces text output. Text output lives in a log file or email inbox. When a teammate asks "are all our SSL certificates healthy?" you can't point them at anything. You have to run the script and parse the output again.

False negatives on connection failures

If a domain becomes unreachable — DNS failure, firewall rule, server down — an openssl check returns empty output. A naive script either logs a warning or skips the domain. A monitoring system distinguishes between "cert is expiring" and "cert is unreachable" and alerts on both.

Certificate chain issues aren't caught

openssl x509 -noout -enddate reads the leaf certificate only. A misconfigured certificate chain (missing intermediate cert) causes browser errors even when the leaf certificate has 90 days remaining. A proper check validates the full chain, not just the expiry date.


What automated multi-domain monitoring looks like

The practical difference between a script and a monitoring service is state management. A monitoring service:

  1. Checks each domain on a defined schedule (every 24 hours is typical)
  2. Records the result with a timestamp
  3. Sends an initial alert when the threshold is crossed
  4. Escalates alerts as expiry approaches (rather than sending the same alert daily)
  5. Sends a distinct alert if the check itself fails (unreachable, chain error, wrong hostname)
  6. Provides a dashboard so the current health of all domains is visible at once
  7. Checks from external infrastructure — so a server-side failure doesn't also take out the monitoring

For teams managing 10 or more SSL certificates, the operational overhead of maintaining a DIY solution usually exceeds the cost of a hosted monitoring service. The failure mode that matters most — a cert that expires because renewal silently broke — is exactly the failure mode that a self-hosted script on the same server won't catch reliably.


Choosing an approach by scale

🔒 Check all your SSL certificates in seconds

Paste any domain into the free SSL Certificate Checker to see expiry, issuer, and chain validity instantly — no signup required. For continuous monitoring across multiple domains, SSLWatch runs checks automatically and alerts you before anything expires.

Check SSL certificate → Monitor multiple domains with SSLWatch

← All articles  ·  SSL checker tool  ·  SSLWatch