Skip to content
ssldays

Guide

Drupal SSL certificate expired

Drupal sites break when hosting TLS expires or reverse-proxy HTTPS settings disagree with the live certificate. Renew at the web server, align trusted_host_settings and base URL, then verify admin and cron over HTTPS.

Updated May 16, 2026 805 words

drupal ssl certificate expired blocks logins, cron, and contrib modules calling https:// on the same host until the web server or proxy presents a current leaf.

Drupal site owners see TLS errors on /user/login, JSON:API endpoints, or CDN-cached pages when the origin certificate expired.

Drupal does not issue TLS; $base_url, reverse proxy headers, and trusted_host_patterns only work after the server handshake succeeds.

Renew infrastructure first, then clear Drupal caches that may still reference broken HTTPS asset URLs.

First response

Confirm the hostname in settings.php or Configuration → System → Basic site settings matches the URL users visit. Run:

drush status --fields=uri,root

Capture openssl from outside for that URI host. If you terminate TLS at Cloudflare or a load balancer, test origin and edge separately—see CDN edge OK but origin certificate expired.

Export drush status and recent nginx error logs before changing trusted_host_patterns. Note whether Symfony reverse proxy headers were recently toggled during a CDN migration. Capture failing JSON:API URLs separately from human-facing routes.

What this error means

Drupal bootstrap over HTTPS requires valid PKIX material on the terminating server. When expired, browsers never reach PHP to evaluate $settings['reverse_proxy'].

After renewal, mis-set trusted_host_patterns or mixed http/https in config can still cause redirect loops—but that is distinct from PKIX expiry.

Drush, Queue UI, and OAuth consumers using TLS to the same host fail with curl errors mirroring browser interstitials.

Drupal expects valid HTTPS before configuration-level HTTPS enforcement matters. Expired hosting TLS blocks bootstrapping far earlier than mis-set base_url strings. Drush remote commands fail PKIX the same way browsers do.

Common causes

Hosting panel AutoSSL failed on the shared vhost serving multisite sites/*/settings.php.

Reverse proxy SSL termination updated only on the edge while Drupal assumes HTTPS to origin.

Multisite alias domains without SAN coverage on the renewed cert.

Acquia/Pantheon-class hosting rarely expires platform TLS; custom domains on external DNS still can.

Long-cached HSTS in browsers after emergency HTTP downgrade attempts.

Configuration splits between settings.php and admin UI can reference https hosts before listeners are ready. Multisite directories map hostnames that never made the CSR SAN list.

Confirm from the outside

OpenSSL

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

Replace HOST with the public hostname users type.

How to read the output

SAN must include the hostname in uri from drush status. Wildcard certs must cover all multisite hostnames.

curl

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

Drupal-specific verification

drush @alias cr
curl -vI https://DRUPALHOST/ 2>&1 | grep -Ei 'expire|SSL certificate'

Inspect settings.php for:

$settings['reverse_proxy'] = TRUE;
$settings['reverse_proxy_trusted_headers'] = \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PROTO | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_HOST;

Adjust only after TLS is valid end-to-end.

Hit varnish or CDN bypass endpoints for origin openssl when Full strict modes apply. Re-run drush status after each certificate change and archive output in the ticket so future multisite migrations inherit a clean baseline.

Fix checklist

  1. Renew TLS at hosting, load balancer, or CDN origin.
  2. Reload web server / ingress.
  3. Ensure base_url and trusted hosts use https://.
  4. drush cr after infrastructure is green.
  5. Test login, cron (drush cron), and JSON:API.
  6. Purge CDN caches.
  7. Search content for hard-coded http:// asset links if mixed warnings remain.
  8. Monitor live TLS on each multisite hostname.

Roll out and verify

Drupal releases and hosting TLS are independent pipelines. Avoid deploying module updates while HTTPS is broken; failed fetches to updates.drupal.org and broken admin JS waste time that belongs on certificate renewal.

Once TLS is valid, run drush updatedb and cron only after trusted_host_patterns matches production URLs. Multisite teams should spot-check sites.php aliases—each hostname listed there needs SAN coverage on the renewed leaf.

Purge reverse-proxy and Drupal render caches in that order: edge first, then Drupal. Stale Twig or page cache can reference https:// asset URLs that were rewritten during the outage window.

Export a post-incident note listing which domain was renewed, who owns DNS, and whether HSTS after expiry elongates browser recovery for returning visitors.

Run drush cron and cache rebuilds only after external TLS is green. Notify editors if HSTS extends browser recovery time. File ticket closure only after update checks succeed remotely.

Coordinators should pause content freezes until TLS is external-green because editors amplify social complaints faster than infrastructure tickets close. Drupal security advisories assume administrators can download updates over HTTPS; an expired certificate therefore blocks patching during the exact window attackers target known CVEs. Separate editorial workflows that fetch remote media over https may queue failures in logs that look like Drupal bugs until infrastructure TLS is repaired. If Redis or Memcached cache backends sit behind TLS tunnels, confirm those tunnels independently—operators sometimes fix public www while administrative cache links still read expired material on an internal hostname. Search API connectors and Solr endpoints using https transport fail with curl errors mirroring browser symptoms; grep recent watchdog entries for Guzzle TLS messages to uncover secondary victims. When Pantheon or Acquia hosts platform TLS, open vendor tickets with external openssl transcripts rather than editing settings.php first. Document which reverse proxy sets X-Forwarded-Proto so future CDN migrations do not repeat partial renewals. Headless decoupled frontends that call Drupal JSON:API share the same server certificate requirements even when React or Next hosts appear healthy. Schedule editor office hours after recovery because authors may still see cached interstitials on corporate DNS until TTLs expire. Post-incident reviews for Drupal should capture which caching layer served stale https asset links and whether configuration exports stored absolute URLs that no longer match renewed SAN lists. Developers running DDEV or Lando locally may not reproduce production PKIX failures; always validate production hostnames remotely before merging config changes that assume TLS is optional. If your team uses OAuth2 login modules, renew callback domain certificates before token exchanges spike support queues. Translation modules that rewrite per-locale domains should each appear in renewal SAN lists. Government and university Drupal installs often delegate TLS to central IT—open bridges early with hosting owners because editorial teams cannot renew listeners themselves. Schedule a follow-up drush status review one week later to ensure cron and update fetches continue succeeding over https.

When to use automation

Certificate files on disk and green panels lie until a stranger's TLS handshake succeeds. Schedule live checks on the exact hostname shoppers or API clients resolve, including redirects and the certificate presented after your platform edge terminates the connection. Pair TLS notAfter with RDAP domain registration data so revalidation is not blocked by registrar billing.

Run a one-shot proof on /check, then add the production hostname to monitoring with alerts at 30, 14, 7, and 1 day thresholds. ssldays reads the live chain external users see—useful when shared hosting, PaaS edges, or CMS layers each claim TLS is fine.

Frequently asked questions

Reverse proxy HTTPS?

Settings must match headers only after certificates are valid.

Multisite SAN?

Every sites.php hostname needs coverage on the listener.

Drush errors after fix?

Run cron and cache rebuild once TLS handshake succeeds.

Acquia or Pantheon?

Platform TLS is managed; custom domains on external DNS can still expire.

See what the server presents right now

Free live certificate check — no signup.