Cybersecurity

How can I check if a certificate is expired or will expire

Monitor certificate expiration dates, implement automated alerting, and prevent service disruptions from expired SSL/TLS certificates.

By Inventive HQ Team

To check when a certificate expires, run echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate — it prints the notAfter (expiry) date for the live certificate. For a local file, use openssl x509 -in cert.pem -noout -enddate; for a quick visual check, click the browser padlock and read "Valid to"; and for scripts, openssl x509 -noout -checkend 2592000 exits non-zero if the certificate expires within the next 30 days. The reliable pattern for production is to check remotely with s_client, compare against your alert thresholds (30, 14, 7, 1 days), and let automated renewal do the actual work.

That's the summary an AI Overview gives you. What it can't give you is the decision of which method to use for which situation, the exact one-liners that survive copy-paste, or the reason this is about to get much harder: certificate lifetimes are shrinking to 47 days by 2029, which makes manual checking obsolete and automation mandatory. This guide covers all of it.

Certificate validity countdown with alert thresholds A certificate lifetime bar draining from valid (green) through the renew window (amber) to expired (red), with alert markers at 30, 14, 7 and 1 days before expiry. A certificate's life is a countdown Check early, alert at multiple thresholds, renew before the red zone. 30 days 14 days 7 days 1 day

Valid Expired

OK — renew automatically Warning — act now Critical — outage imminent

How to Check Certificate Expiration: Every Method Compared

There is no single "right" way to check a certificate's expiry date — the best tool depends on whether you have shell access, a local file, or need continuous alerting. This table maps each method to the situation it fits, with a copy-paste command for each.

MethodCommand / HowBest forNotes
Browser padlockClick the padlock → Certificate (or "Connection is secure" → "Certificate is valid") → read Valid toA quick one-off visual checkNo CLI needed; browser may show local time, not UTC
openssl x509 (local file)openssl x509 -in cert.pem -noout -enddateA certificate file already on diskAdd -dates to see both notBefore and notAfter
openssl s_client (live server)echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddateChecking what's actually deployed on an endpoint-servername sends SNI (required for multi-cert hosts)
curl -vIcurl -vI https://example.com 2>&1 | grep "expire date"A fast check with a tool you already haveReads curl's own verbose TLS output; no OpenSSL needed
openssl -checkend (scripts)echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -checkend 2592000Cron / CI gatingExit code 1 if it expires within 2,592,000s (30 days); 0 if still valid
Online checkerPaste the hostname into an SSL checker (SSL Labs, or the tool below)No shell access, or sharing a shareable reportReads the public endpoint; can also flag chain/protocol issues
Monitoring platformDatadog / UptimeRobot / Pingdom, Prometheus ssl_exporter, or cert-manager metricsContinuous alerting across many hostsThe only option that scales; alerts at configurable thresholds

Which should I use? For a one-off human check, the browser padlock or curl -vI. For scripting and CI, openssl ... -checkend. For production fleets, a monitoring platform is the only answer that scales — and with 47-day certificates arriving (see below), it's no longer optional.

Loading interactive tool...

The Importance of Certificate Expiration Monitoring

When an SSL/TLS certificate expires, HTTPS connections fail. Browsers display security warnings, users can't access the site, and services relying on HTTPS are disrupted. Despite this serious consequence, certificate expiration remains one of the most common causes of unexpected downtime in production systems. Many organizations have experienced the embarrassment of a high-profile service going down because someone forgot to renew a certificate.

Preventing certificate expiration problems requires both automated monitoring and renewal processes. You need to know well in advance when certificates will expire so you have time to renew them, and you need systems in place to automatically check expiration dates and alert you before it's too late.

Manual Certificate Expiration Checking

Using OpenSSL:

# Check expiration of a certificate file
openssl x509 -in certificate.crt -noout -dates

# Output:
# notBefore=Jan 15 12:34:56 2024 GMT
# notAfter=Apr 14 12:34:56 2024 GMT

# Extract just the expiration date
openssl x509 -in certificate.crt -noout -enddate

# Output:
# notAfter=Apr 14 12:34:56 2024 GMT

Checking a live HTTPS server's certificate:

# Connect to server and retrieve certificate
openssl s_client -connect example.com:443 -servername example.com < /dev/null | openssl x509 -noout -dates

# For just the expiration date:
openssl s_client -connect example.com:443 -servername example.com < /dev/null | openssl x509 -noout -enddate

Using curl:

# Check certificate expiration from a URL
curl -vI https://example.com 2>&1 | grep "expire date"

# Output:
# *    expire date: Apr 14 12:34:56 2024 GMT

Using Python:

from datetime import datetime
import ssl

def check_certificate_expiration(hostname, port=443):
    context = ssl.create_default_context()
    try:
        with context.create_connection((hostname, port), timeout=10) as sock:
            with context.wrap_socket(sock, server_hostname=hostname) as ssock:
                cert = ssock.getpeercert()
                expiration = datetime.strptime(
                    cert['notAfter'],
                    '%b %d %H:%M:%S %Y %Z'
                )

                days_until_expiration = (expiration - datetime.now()).days

                print(f"Certificate expires: {expiration}")
                print(f"Days until expiration: {days_until_expiration}")

                if days_until_expiration < 0:
                    print("CRITICAL: Certificate is EXPIRED")
                elif days_until_expiration < 30:
                    print(f"WARNING: Certificate expires in {days_until_expiration} days")
                else:
                    print(f"OK: Certificate is valid for {days_until_expiration} more days")

                return expiration, days_until_expiration
    except Exception as e:
        print(f"Error checking certificate: {e}")
        return None, None

# Usage
check_certificate_expiration('example.com')

Using JavaScript (Node.js):

const https = require('https');
const tls = require('tls');

function checkCertificateExpiration(hostname) {
  const options = {
    hostname: hostname,
    port: 443,
    method: 'HEAD'
  };

  const req = https.request(options, (res) => {
    const cert = res.socket.getPeerCertificate();
    const expirationDate = new Date(cert.valid_to);
    const now = new Date();
    const daysUntilExpiration = Math.floor((expirationDate - now) / (1000 * 60 * 60 * 24));

    console.log(`Certificate expires: ${expirationDate}`);
    console.log(`Days until expiration: ${daysUntilExpiration}`);

    if (daysUntilExpiration < 0) {
      console.log('CRITICAL: Certificate is EXPIRED');
    } else if (daysUntilExpiration < 30) {
      console.log(`WARNING: Certificate expires in ${daysUntilExpiration} days`);
    } else {
      console.log(`OK: Certificate is valid for ${daysUntilExpiration} more days`);
    }

    res.resume();
  });

  req.on('error', (err) => {
    console.error(`Error checking certificate: ${err.message}`);
  });

  req.end();
}

// Usage
checkCertificateExpiration('example.com');
Advertisement

Automated Certificate Expiration Monitoring

For production systems, manual checking isn't sufficient. You need automated monitoring that regularly checks expiration dates and alerts you before expiration.

Monitoring Tools:

  1. Uptime/Monitoring Services:
    • Uptimerobot
    • Pingdom
    • New Relic
    • Datadog

These services monitor HTTPS endpoints and can alert when certificate expiration is approaching (typically configurable for 30, 14, 7, and 1-day warnings).

  1. Certificate Management Tools:
    • Sectigo (formerly Comodo)
    • DigiCert
    • GlobalSign

Most commercial CA platforms offer monitoring and automated renewal.

  1. Open Source Tools:

    • Certbot (from Let's Encrypt)
    • Acme.sh
    • cert-manager (Kubernetes)
  2. Custom Scripts: Create monitoring scripts that check certificates on a schedule.

Example Monitoring Script (Bash):

#!/bin/bash

HOSTNAME="example.com"
ALERT_THRESHOLD_DAYS=30
EMAIL_ALERT="admin@example.com"

# Get certificate expiration date
EXPIRATION=$(echo | openssl s_client -servername $HOSTNAME -connect $HOSTNAME:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)

# Convert to seconds since epoch
EXPIRATION_EPOCH=$(date -d "$EXPIRATION" +%s)
NOW_EPOCH=$(date +%s)

# Calculate days until expiration
DAYS_UNTIL=$((($EXPIRATION_EPOCH - $NOW_EPOCH) / 86400))

# Check and alert
if [ $DAYS_UNTIL -lt 0 ]; then
    echo "CRITICAL: Certificate for $HOSTNAME is EXPIRED" | mail -s "CRITICAL: Certificate Expired" $EMAIL_ALERT
elif [ $DAYS_UNTIL -lt $ALERT_THRESHOLD_DAYS ]; then
    echo "WARNING: Certificate for $HOSTNAME expires in $DAYS_UNTIL days" | mail -s "WARNING: Certificate Expiring" $EMAIL_ALERT
else
    echo "OK: Certificate for $HOSTNAME is valid for $DAYS_UNTIL more days"
fi

Add this to cron to run regularly:

# Check certificate expiration daily
0 9 * * * /path/to/check_cert_expiration.sh

Example Monitoring with Prometheus (Node Exporter): The Node Exporter has a textfile_collector that can run scripts reporting metrics.

Create a script that outputs Prometheus metrics:

#!/bin/bash

HOSTNAME="example.com"

# Get certificate expiration in Unix timestamp
EXPIRATION=$(echo | openssl s_client -servername $HOSTNAME -connect $HOSTNAME:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRATION_EPOCH=$(date -d "$EXPIRATION" +%s)

# Output Prometheus metric
echo "# HELP certificate_expires_seconds_unix Certificate expiration time in Unix epoch"
echo "# TYPE certificate_expires_seconds_unix gauge"
echo "certificate_expires_seconds_unix{hostname=\"$HOSTNAME\"} $EXPIRATION_EPOCH"

Then Prometheus can alert when the expiration time is approaching:

groups:
  - name: certificates
    rules:
    - alert: CertificateExpiresSoon
      expr: (certificate_expires_seconds_unix - time()) / 86400 < 30
      for: 1h
      annotations:
        summary: "Certificate expires in less than 30 days"

Kubernetes Certificate Monitoring

For Kubernetes clusters, certificate expiration is a common operational challenge:

Using cert-manager:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-cert
spec:
  secretName: example-tls
  issuerRef:
    name: letsencrypt-prod
  dnsNames:
  - example.com
  - www.example.com
  # Auto-renew 30 days before expiration
  renewBefore: 720h  # 30 days

Monitoring with Prometheus:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: certificate-alerts
spec:
  groups:
  - name: certificates
    interval: 30s
    rules:
    - alert: KubernetesCertificateExpiresSoon
      expr: certmanager_certificate_renewal_errors_total > 0
      for: 1h
      annotations:
        summary: "Certificate renewal error detected"

    - alert: KubernetesCertificateExpires
      expr: certmanager_certificate_expiration_timestamp_seconds - time() < 604800
      # Triggers 7 days before expiration
      for: 1h
      annotations:
        summary: "Certificate expires in less than 7 days"

Automated Certificate Renewal

Prevention is better than cure. Use automated renewal instead of manual renewal:

Let's Encrypt with Certbot:

# Install certbot
apt-get install certbot python3-certbot-nginx

# Get certificate
certbot certonly --nginx -d example.com -d www.example.com

# Set up auto-renewal (installed by default)
systemctl enable certbot.timer
systemctl start certbot.timer

# Check renewal status
certbot renew --dry-run

Certbot automatically renews certificates 30 days before expiration.

Docker-based Renewal:

FROM certbot/certbot
WORKDIR /etc/letsencrypt
VOLUME /etc/letsencrypt
ENTRYPOINT ["certbot", "renew", "--webroot", "-w", "/var/www/html"]

Run as a cron job:

docker run --rm \
  -v /etc/letsencrypt:/etc/letsencrypt \
  -v /var/www/html:/var/www/html \
  certbot/certbot \
  renew

Why This Gets Harder: 47-Day Certificates by 2029

In April 2025 the CA/Browser Forum passed Ballot SC-081v3 (29 votes in favour, zero against), committing every publicly trusted CA to a phased reduction of the maximum TLS certificate lifetime from today's 398 days down to 47 days by March 15, 2029. The domain-validation reuse window shrinks alongside it, so you re-prove control of your domain far more often too.

Effective dateMax certificate lifetimeMax domain-validation reuse
Now (through Mar 2026)398 days398 days
March 15, 2026200 days200 days
March 15, 2027100 days100 days
March 15, 202947 days10 days
Certificate lifetime shrinking from 398 to 47 days Bar chart showing the maximum certificate validity dropping from 398 days now to 200 days in 2026, 100 days in 2027, and 47 days in 2029. Max certificate lifetime is collapsing 398 days · now
<rect x="40" y="130" width="0" height="30" rx="6" fill="#2813e8">
  <animate attributeName="width" values="0;301" dur="1.2s" begin="0.2s" fill="freeze"/>
</rect>
<text x="355" y="151" font-size="14" font-weight="700" fill="#0f172a">200 &middot; Mar 2026</text>

<rect x="40" y="170" width="0" height="30" rx="6" fill="#f59e0b">
  <animate attributeName="width" values="0;151" dur="1.2s" begin="0.4s" fill="freeze"/>
</rect>
<text x="205" y="191" font-size="14" font-weight="700" fill="#0f172a">100 &middot; Mar 2027</text>

<rect x="40" y="210" width="0" height="30" rx="6" fill="#dc2626">
  <animate attributeName="width" values="0;71" dur="1.2s" begin="0.6s" fill="freeze"/>
</rect>
<text x="125" y="231" font-size="14" font-weight="700" fill="#0f172a">47 &middot; Mar 2029</text>

At a 47-day lifetime you would need to renew roughly every six weeks — far too often to survive on calendar reminders or a spreadsheet. The practical consequence is simple: manual renewal stops being viable and ACME-based automation (Let's Encrypt/Certbot, cert-manager, or your CA's ACME endpoint) becomes the only sustainable model. Start migrating any manually renewed certificate to automated issuance now, well before the 2026 cutover forces the issue.

Monitoring Across an Organization

For enterprises with many certificates:

Certificate Inventory: Maintain a database of all certificates:

  • Hostname
  • Certificate authority
  • Expiration date
  • Renewal date
  • Owner contact

Centralized Monitoring: Use CMDB (Configuration Management Database) tools:

  • Splunk
  • ServiceNow
  • Custom dashboard

Alerting Strategy: Set up alerts at multiple thresholds:

  • 90 days before expiration: Info
  • 30 days before expiration: Warning
  • 7 days before expiration: Critical alert to responsible team
  • Expired: Critical incident

Reporting: Generate monthly reports of certificate status across the organization.

Troubleshooting Certificate Expiration Issues

Problem: Certificate Shows as Expired but Browser Accepts It: Likely cause: Your system time is incorrect. Certificates are time-based. Solution: Sync system time: ntpdate -s time.nist.gov

Problem: Certificate Renewal Failed: Causes:

  • DNS not pointing to verification server
  • Firewall blocking challenge port
  • Disk space exhausted

Solution: Check renewal logs and DNS configuration.

Problem: Intermediate Certificate Missing: If the certificate chain is incomplete, browsers may reject it. Solution: Include intermediate certificate in certificate bundle.

Best Practices

  1. Automate everything: Use Let's Encrypt and certbot or equivalent for automatic renewal
  2. Multiple alert levels: Alert progressively as expiration approaches
  3. Test renewal: Regularly test that renewal processes work
  4. Monitor across your entire organization: Know every certificate you operate
  5. Use DNS-based validation: More reliable than HTTP validation
  6. Plan for shrinking lifetimes: Maximum validity drops to 200 days in March 2026, 100 days in 2027, and 47 days in 2029 — assume renewal will be too frequent to do by hand and move to ACME automation now

Conclusion

Certificate expiration doesn't have to cause downtime. With proper monitoring (automated checking at multiple thresholds), automated renewal (using Let's Encrypt or similar), and good organizational practices (maintaining certificate inventory, understanding the renewal process), you can ensure your certificates never unexpectedly expire. The best approach is to fully automate both monitoring and renewal, treating certificate management as a solved technical problem rather than a manual operational burden.

Frequently Asked Questions

How do I check when an SSL certificate expires using OpenSSL?

Use the command: openssl x509 -in certificate.crt -noout -enddate. This outputs the expiration date in GMT. For a live server: openssl s_client -connect domain.com:443 -servername domain.com < /dev/null 2>/dev/null | openssl x509 -noout -enddate. Add -dates instead of -enddate to see both the "not before" and "not after" dates.

How do I check certificate expiration in a browser?

Click the padlock icon in the address bar, then click "Certificate" or "Connection is secure" > "Certificate is valid". The certificate details show validity dates under "Valid from" and "Valid to" (or "Expires"). In Chrome DevTools, go to Security tab > View certificate. Firefox shows it under the lock icon > Connection secure > More information.

How many days before expiration should I renew certificates?

Renew at least 30 days before expiration for manual processes, allowing time to troubleshoot issues. For automated renewal (Let's Encrypt/Certbot), the default is 30 days, but you can safely reduce to 7-14 days if your automation is reliable. Set up alerts at 30, 14, 7, and 1 day before expiration as a safety net.

How do I set up automated certificate expiration monitoring?

Use tools like Nagios/Icinga with check_ssl_cert plugin, Prometheus with ssl_exporter, or cloud-native solutions (AWS Config rules, Azure Monitor). For simple monitoring, create a cron job running: echo | openssl s_client -servername domain.com -connect domain.com:443 2>/dev/null | openssl x509 -noout -checkend 2592000 (checks if expiring within 30 days, returns exit code 1 if true).

What happens if my SSL certificate expires?

Browsers display security warnings like "NET::ERR_CERT_DATE_INVALID" or "Your connection is not private." Users cannot access your site without bypassing the warning (which many won't do). APIs and services fail with TLS handshake errors. Search rankings may drop. Automated systems break. Expired certificates are a leading cause of outages—prevention is critical.

How do I check certificate expiration for multiple domains at once?

Create a script that loops through domains and checks each with OpenSSL. Tools like ssl-cert-check, check_ssl_cert, or cert-manager's cert-manager status command handle batch checking. Commercial solutions (Venafi, DigiCert CertCentral, Keyfactor) provide dashboards for enterprise certificate inventory. Many monitoring platforms (Datadog, New Relic) have SSL monitoring built-in.

Can I check certificate expiration without connecting to the server?

Yes, if you have the certificate file locally: openssl x509 -in cert.pem -noout -enddate. You can also query Certificate Transparency logs (crt.sh) to see certificates issued for your domain and their expiration dates. However, CT logs show issuance—the actual deployed certificate may differ, so direct checking is more reliable.

How do I check certificate expiration in Kubernetes?

For cert-manager: kubectl get certificates -A shows status including expiration. kubectl describe certificate <name> shows detailed timing. For manual checks: kubectl get secret <tls-secret> -o jsonpath='{.data.tls.crt}' | base64 -d | openssl x509 -noout -enddate. Use cert-manager's built-in metrics for Prometheus monitoring.

Why does my certificate show different expiration dates in different tools?

Timezone differences—OpenSSL shows UTC/GMT, browsers may show local time. Also, some tools show the leaf certificate while others show intermediate or root CAs (which have different expiration dates). Always check the end-entity/leaf certificate. Use openssl x509 -in cert.pem -noout -subject -enddate to confirm you're checking the right certificate.

How do I check if a certificate will expire within a specific number of days?

Use OpenSSL's -checkend flag with seconds: openssl x509 -in cert.pem -noout -checkend 2592000 checks if expiring within 30 days (30 × 24 × 60 × 60 = 2592000 seconds). Exit code 0 means valid beyond that time; exit code 1 means it expires within that window. For remote: echo | openssl s_client -connect domain.com:443 2>/dev/null | openssl x509 -noout -checkend 2592000.

certificate managementSSL/TLSexpiration monitoringcertificate renewalDevOps