Skip to content
ssldays

Guide

curl: SSL certificate problem: certificate has expired

curl exits with SSL certificate problem: certificate has expired when notAfter is in the past. Use openssl and curl -v to confirm, then renew and reload the service presenting the cert.

Updated Mar 19, 2026 939 words

When curl reports that the certificate has expired, OpenSSL rejected notAfter during the HTTPS handshake—renew the cert on the listener for that URL.

Deploy scripts and cron jobs fail loudly with exit code 60 while browsers still show a nicer error page. curl uses the platform trust store and strict verification by default, so it is an honest witness of production TLS.

Teams sometimes add -k during panic, which hides the problem while leaving customers unprotected. Use verbose curl without insecure flags to document the incident, then fix the certificate.

First response

curl exits with SSL certificate problem: certificate has expired when notAfter is in the past. Use openssl and curl -v to confirm, then renew and reload the service presenting the cert.

Search interest in curl ssl certificate expired rises when the leaf notAfter on the hostname customers type is already in the past. Clients cannot rewrite server certificate dates; they only accept chains that pass PKIX checks at handshake time.

For curl: SSL certificate problem: certificate has expired, prove the failure from outside your office VPN before you change application code, purge caches, or ask end users to reboot. Capture the broken serial number and notAfter, renew on the listener that actually terminates that name, reload every node in the path, then re-run the same OpenSSL and browser checks that opened the incident.

Escalations for curl-ssl-certificate-expired should cite fresh curl -v alongside openssl x509 -noout -dates on the same URL output before anyone edits client code or blames Wi‑Fi. curl exits with SSL certificate problem: certificate has expired when notAfter is in the past. Use openssl and curl -v to confirm, then renew and reload the service presenting the cert. When SSL certificate problem: certificate has expired clusters around curl and libcurl clients, the expired material is usually bound to the HTTPS endpoint your scripts call instead of a mysterious platform bug. Executive summaries need the public hostname and current notAfter, not screenshots from a VPN-split test laptop.

See also wget certificate verify failed expired and Load balancer presenting an expired certificate.

What this error means

libcurl delegates certificate verification to OpenSSL or Schannel depending on build. Expired leaf or intermediate certificates fail before HTTP headers return, which is why curl -I dies at TLS.

Redirects matter: curl follows to a new host that may present a different certificate. Capture the failing hostname from verbose output, not only the first URL typed.

After renewal, the same curl command should complete without -k and show HTTP status lines. Keep that command as a synthetic monitor.

In PKIX terms, curl and libcurl clients treat the TLS Certificate message as authoritative: signatures must verify, each link must be within notBefore/notAfter, and only then does name matching run against CN and SAN. When the leaf expired, SSL certificate problem: certificate has expired is expected even if the issuer is publicly trusted. Guides titled curl ssl certificate expired still require reading dates on every certificate the server sends, including forgotten cross-sign intermediates.

Triage for curl ssl certificate expired should reject quick myths: flushing DNS or rebooting laptops does not move server notAfter forward. It is not proof the whole internet is broken when other HTTPS sites load for curl and libcurl clients. It is not interchangeable with registrar billing lapses unless revalidation fails later. It is not fixed by turning off TLS at the load balancer while marketing keeps publishing https:// links. Validated externally, curl -v alongside openssl x509 -noout -dates on the same URL must show fresh dates on the HTTPS endpoint your scripts call before you close the incident.

Common causes

These patterns appear often during curl ssl certificate expired incidents. They are not exhaustive, but they explain why renewal looked finished internally while strangers still received expired material.

Runbooks for curl ssl certificate expired most often break at handoff: certbot or a vendor portal issued new certs, but the HTTPS endpoint your scripts call never received a reload. Teams tracked PEM files in git while production continued serving the previous listener binding. OV renewals waited on legal approvers until SSL certificate problem: certificate has expired became customer-visible. Inventory spreadsheets omitted the hostname that curl and libcurl clients actually call during peak traffic.

Architecture amplifies curl ssl certificate expired: multiple regions, canary pools, or blue/green deploys can leave one ASG member presenting yesterday's fullchain. Shared IP default certificates silently terminate vanity hostnames without dedicated SNI rules. Mounted TLS secrets updated on disk while Envoy or nginx workers kept the old chain until signaled. curl exits with SSL certificate problem: certificate has expired when notAfter is in the past becomes harder to debug when only a fraction of curl and libcurl clients hit the stale anycast node.

Measurement gaps complete the story for curl ssl certificate expired. Synthetic monitors that disable certificate verification greenlit deploys that fail for real curl and libcurl clients. Redirect maps hid which hop expired until operators ran curl -v alongside openssl x509 -noout -dates on the same URL per hostname. Dashboards celebrated TCP uptime while notAfter crossed midnight UTC without a page. Post-mortems should ask whether CT logs or stapled OCSP would have warned days earlier.

Confirm from the outside

OpenSSL

echo | openssl s_client -connect HOST:443 -servername HOST 2>/dev/null | openssl x509 -noout -dates -subject -issuer

Match the hostname curl ultimately connects to; use -servername for virtual hosts.

How to read the output

Start with curl -v alongside openssl x509 -noout -dates on the same URL against the live customer hostname, capturing the leaf presented after SNI selection. Interpret notBefore= and notAfter= first: past notAfter guarantees failure for SSL certificate problem: certificate has expired regardless of pretty issuer branding. Next read subject= and any X509v3 Subject Alternative Name extension for alignment with the URL bar. Finally note issuer= so you know whether renewal changed intermediates; record serial numbers in the ticket for post-deploy diffing.

curl

curl -vI --connect-timeout 10 https://HOST/ 2>&1 | grep -Ei 'expire|SSL certificate|subject:|issuer:'

Save curl -v output to the ticket; grep for expire and certificate problem lines.

Browser spot-check

Browsers should fail in parallel; curl is not wrong when Chrome also blocks the site.

Fix checklist

Work this list in order for curl: ssl certificate problem: certificate has expired. Each step should produce evidence (command output, timestamps, serial numbers) you can paste into the incident ticket.

  1. Re-run curl -v without -k from CI and from an external host.
  2. Note the SNI hostname that presented the expired cert.
  3. Renew on that terminator with full chain attached.
  4. Update secrets or paths if automation deploys PEM files.
  5. Reload services; rerun curl until HTTP headers appear.
  6. Remove temporary --insecure flags from scripts.
  7. Add the successful curl command to uptime checks.
  8. Archive openssl dates in the incident doc.

Roll out and verify

Procurement for curl ssl certificate expired begins with a reissue that lists every hostname curl and libcurl clients need, including forgotten admin and callback URLs. Validate CSR/key pairs, download CA bundles, and schedule work on the HTTPS endpoint your scripts call during a staffed change window. If automation handles ACME, prove challenges use the same DNS names customers resolve publicly, not internal-only labels.

Installation for curl ssl certificate expired means concatenating leaf and required intermediates the way your stack documents, then touching every node that terminates the name. Reload web servers, recycle ingress pods, or update cloud listener objects so data planes read new bytes. For load balancers, sync default and per-host certificates so SNI cannot fall back to expired defaults. Repeat curl -v alongside openssl x509 -noout -dates on the same URL until fingerprints or serials change everywhere responders tested earlier.

Verification for curl ssl certificate expired must mimic strangers: external synthetics, mobile carriers, and CI jobs without corporate trust roots. Confirm SSL certificate problem: certificate has expired disappeared for curl and libcurl clients on flows heavier than GET /. Restore any strict TLS, HSTS, or CDN SSL modes relaxed during firefighting. Feed the hostname into continuous notAfter monitoring with thresholds well before the next CA-enforced renewal cliff.

What to automate

Certificate files on disk lie. Automate live TLS checks on the exact hostname and port users hit, including redirects and the certificate presented after TLS terminates on a load balancer or CDN. Pair certificate notAfter with RDAP domain registration expiry so re-validation is not blocked by a lapsed registrar.

Mirror production curl probes in CI on every deploy. Schedule alerts at 30, 14, 7, and 1 day before expiry so on-call has runway for ACME failures, manual OV revalidation, or change windows. Services such as ssldays can run external checks and renewal reminders without replacing your CA workflow.

Frequently asked questions

Why exit code 60?

curl uses 60 for peer certificate failures, including expiry. Treat sustained 60s from monitors as production down for that URL. Correlate with OpenSSL notAfter before chasing application bugs.

Does Jenkins behave differently?

Agents may ship older CA bundles, but an expired server cert fails everywhere. Still compare agent time sync and proxy settings if only CI fails.

What about HTTP/3?

QUIC still presents X.509 certificates with the same validity window. Renewal and reload requirements match HTTPS on port 443.

Should I trust `--cacert` overrides?

Custom CA files are for private PKI, not for extending expired public certs. Fix publicly trusted material on the server for internet endpoints.

See what the server presents right now

Free live certificate check — no signup.