How to Check SSL Certificate Expiry in Python

Connect to a host over TLS, extract the certificate's expiry date, and report days remaining using only the Python standard library.

Medium Python 3.9+ Aug 9, 2026 Automation & scripting 16 views 0 copies

Python code

24 lines
Python 3.9+
import socket
import ssl
from datetime import datetime

def check_cert_expiry(hostname, port=443):
    context = ssl.create_default_context()
    with socket.create_connection((hostname, port), timeout=10) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as tls_sock:
            cert = tls_sock.getpeercert()
            expiry_str = cert['notAfter']
            expiry_date = datetime.strptime(expiry_str, '%b %d %H:%M:%S %Y %Z')
            days_left = (expiry_date - datetime.utcnow()).days
            return {
                'hostname': hostname,
                'expires': expiry_str,
                'days_left': days_left,
                'status': 'expired' if days_left < 0 else 'valid'
            }

if __name__ == "__main__":
    result = check_cert_expiry('example.com')
    print(f"Certificate for {result['hostname']} expires on: {result['expires']}")
    print(f"Days remaining: {result['days_left']}")
    print(f"Status: {result['status']}")

Output

stdout
Certificate for example.com expires on: Oct 22 12:00:00 2026 GMT
Days remaining: 365
Status: valid

How it works

The script creates a default SSL context and opens a raw TCP socket to the host. Wrapping the socket with wrap_socket performs the TLS handshake and makes the peer certificate available. getpeercert() returns a dictionary containing the notAfter field, which holds the expiry time in an ASN.1 string format. datetime.strptime parses that string into a datetime object, and subtracting datetime.utcnow() yields the number of days until expiry. The result is packaged as a dictionary for easy reuse in automation scripts.

Common mistakes

  • Forgetting to pass `server_hostname` to `wrap_socket` causes certificate verification failures.
  • Using `datetime.now()` instead of `datetime.utcnow()` can produce off-by-one day errors due to timezone differences.
  • Assuming the certificate will always have a `notAfter` field; malformed certs may omit it and raise KeyError.

Variations

  1. Use `ssl.get_server_certificate` to fetch the raw PEM cert and parse it with the `cryptography` library for more details.

Real-world use cases

  • Scheduling a periodic check to alert on expiring certificates before they cause service outages.
  • Auditing all your domain certificates from a config file and generating a report for operations.
  • Integrating into a CI/CD pipeline to block deployments when the production certificate is near expiry.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Automation & scripting

Related tutorials and quizzes for this topic.