/ โ† HTTP Error Fixes / SSL Handshake Errors
In this guide
  1. What happens in the handshake
  2. Reading the error message
  3. Testing the certificate from the command line
  4. Expired certificates and failed renewals
  5. Hostname mismatches
  6. Incomplete certificate chains
  7. Protocol and cipher mismatches
  8. The fix, step by step
  9. Keeping certificates healthy
  10. Questions and answers

What happens in the handshake

When a visitor opens https://www.example.co.uk/, their browser and your server run through a short negotiation before any page is requested:

  1. The browser says which TLS versions and encryption methods it supports, and which hostname it wants. Sending the hostname at this stage is called SNI, and it is how one server with one IP address can hold certificates for many sites.
  2. The server picks a version and method, and sends its certificate plus any intermediate certificates that link it to a trusted authority.
  3. The browser checks the certificate: is it in date, does it name this hostname, and does the chain lead to a root authority the browser already trusts?
  4. If everything checks out, both sides set up encryption and the ordinary HTTP request begins.

A failure at step 2 or 3 means there is no HTTP response at all, which is why an audit reports an SSL error rather than a status code. It also means one bad certificate breaks every page on that hostname at the same moment.

Reading the error message

Browsers name the specific check that failed. The name is the most useful clue you have, so copy it exactly before doing anything else.

Chrome and EdgeFirefoxWhat failed
NET::ERR_CERT_DATE_INVALIDSEC_ERROR_EXPIRED_CERTIFICATEThe certificate has expired, or is not valid yet. Can also be caused by a wrong clock on the visitor's device.
NET::ERR_CERT_COMMON_NAME_INVALIDSSL_ERROR_BAD_CERT_DOMAINThe certificate does not list the hostname in the address bar.
NET::ERR_CERT_AUTHORITY_INVALIDSEC_ERROR_UNKNOWN_ISSUERThe browser cannot link the certificate to a trusted root: a self-signed certificate, or a missing intermediate.
ERR_SSL_VERSION_OR_CIPHER_MISMATCHSSL_ERROR_NO_CYPHER_OVERLAPThe server only offers old protocols or ciphers the browser no longer accepts.
ERR_SSL_PROTOCOL_ERRORSSL_ERROR_RX_RECORD_TOO_LONGThe server did not answer with TLS at all, often because port 443 is serving plain HTTP.

Behind Cloudflare there are two more to know. Error 525 means Cloudflare could not complete a handshake with your origin server, and error 526 means the origin's certificate was not valid when Cloudflare's SSL mode is set to check it strictly. In both cases visitors' browsers are fine; the problem is between Cloudflare and your server.

โš ๏ธ Never tell visitors to click through a certificate warning. On sites that send an HSTS header, browsers do not even offer that option, and for everyone else it teaches them to ignore a real security signal.

Testing the certificate from the command line

Browsers cache intermediate certificates and sometimes fetch missing ones on their own, so a site can look fine in your browser while failing for crawlers, older phones and command-line tools. openssl shows exactly what the server sends.

# What does the server send for this hostname? Always include -servername.
openssl s_client -connect www.example.co.uk:443 -servername www.example.co.uk -showcerts </dev/null

# Expiry dates, subject and the hostnames the certificate covers
openssl s_client -connect www.example.co.uk:443 -servername www.example.co.uk </dev/null 2>/dev/null \
  | openssl x509 -noout -dates -subject -issuer -ext subjectAltName

# Does a normal client accept it? curl fails loudly on chain and name problems
curl -sv -o /dev/null https://www.example.co.uk/ 2>&1 | grep -iE "SSL|certificate|subject|expire"

What to look for in the output:

๐Ÿ’ก Leaving out -servername shows you the server's default certificate, not the one for your site. If the test without it shows another domain's certificate, that is exactly what very old clients without SNI support would see, but it is not what modern browsers receive.

Expired certificates and failed renewals

Most expiry problems are really renewal problems. Free certificates from Let's Encrypt last 90 days and are meant to renew automatically, and the maximum lifetime of all publicly trusted certificates is being reduced in stages under CA/Browser Forum rules, starting in 2026. Manual renewal is becoming impractical, so the aim is a renewal process that works on its own and tells you when it does not.

Common reasons automatic renewal stops:

# Certbot: list certificates and their expiry, then rehearse a renewal
sudo certbot certificates
sudo certbot renew --dry-run
# After a real renewal, reload the web server so it uses the new files
sudo systemctl reload nginx

If only one visitor sees a date error while everyone else is fine, check that visitor's device clock. A clock set months out causes a date error on every HTTPS site they visit.

Hostname mismatches

A certificate covers exactly the names listed in its subject alternative names, and nothing else. The most frequent gaps are:

# Issue one certificate covering both names with certbot and nginx
sudo certbot --nginx -d example.co.uk -d www.example.co.uk

Once both names have a valid certificate, redirect one to the other with a single 301. Redirect order and HTTPS redirects are covered in the HTTPS redirects guide.

Incomplete certificate chains

Your certificate is signed by an intermediate certificate, which is signed by a root that browsers trust. The server must send your certificate and the intermediates; the root is already on the visitor's device. If the intermediate is missing, desktop browsers that have seen it before may cope, while crawlers, API clients, some Android devices and command-line tools fail with an unknown issuer error. This is one of the most common reasons an audit reports an SSL error that you cannot reproduce in your own browser.

The fix is to point the server at the full chain file rather than the certificate on its own:

# nginx
ssl_certificate     /etc/letsencrypt/live/example.co.uk/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.co.uk/privkey.pem;

# Apache 2.4.8 and later
SSLCertificateFile    /etc/letsencrypt/live/example.co.uk/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.co.uk/privkey.pem

With a certificate bought from a commercial authority, you usually receive your certificate and a separate bundle of intermediates. For nginx, join them into one file with your certificate first and the intermediates after it. Hosting panels usually have a separate field for the intermediate or CA bundle; make sure it is filled in.

Protocol and cipher mismatches

TLS 1.0 and 1.1 are formally deprecated and current browsers refuse them. A server that only offers those versions, or only very old ciphers, produces a version or cipher mismatch error in every modern browser. The opposite problem also happens: a server locked down to TLS 1.3 only can refuse older but still reasonable clients, including some crawlers and business systems.

A sensible setting for most public sites in 2026 is TLS 1.2 and TLS 1.3 enabled, with nothing older:

# nginx
ssl_protocols TLSv1.2 TLSv1.3;

# Apache
SSLProtocol -all +TLSv1.2 +TLSv1.3
# Check which versions the server accepts
openssl s_client -connect www.example.co.uk:443 -servername www.example.co.uk -tls1_2 </dev/null
openssl s_client -connect www.example.co.uk:443 -servername www.example.co.uk -tls1_3 </dev/null

An ERR_SSL_PROTOCOL_ERROR with no certificate at all often means port 443 is answering with plain HTTP, usually because the ssl parameter is missing from an nginx listen 443 line, or a load balancer is forwarding to the wrong port.

Behind a CDN

With Cloudflare or a similar CDN, there are two connections: visitor to CDN, and CDN to your server. Use a mode that encrypts and validates the second connection, called Full (strict) in Cloudflare, and give your origin a valid certificate, either a public one or the CDN's own origin certificate. A 525 means the origin handshake failed; check that the origin listens on 443 with TLS and accepts TLS 1.2 or later. A 526 means the origin certificate is expired, self-signed or for the wrong name.

The fix, step by step

Step 1

Read the exact error name

Open the hostname the HTTP Error Audit flagged in a browser and note the precise error code, such as NET::ERR_CERT_DATE_INVALID or SEC_ERROR_UNKNOWN_ISSUER. The name tells you which check failed: date, hostname, chain or protocol. If the site sits behind Cloudflare and shows error 525 or 526, the problem is on the connection from Cloudflare to your origin server rather than in the visitor's browser.

Step 2

Inspect the certificate the server sends

Run openssl s_client with -connect and -servername set to the failing hostname, adding -showcerts to print the chain. Pipe it through openssl x509 -noout -dates -ext subjectAltName to read the expiry date and the covered names. Check that the verify return code at the end is 0. Test both the www and bare domain, because each can be configured separately.

Step 3

Renew an expired certificate and fix renewal

Renew the certificate through your host, panel or certbot renew, then reload the web server so it loads the new file. Run certbot renew --dry-run to prove the next renewal will work. If it fails, make sure /.well-known/acme-challenge/ is reachable over HTTP, remove stale DNS records such as an old AAAA record, and confirm the renewal timer or cron job exists.

Step 4

Cover every hostname you serve

Compare the subject alternative names on the certificate with every hostname that receives traffic: the bare domain, www, subdomains and any old domains that redirect. Reissue the certificate with all of them, remembering that a wildcard covers only one level and not the bare domain. Make sure each hostname is attached to the right site on the server, so nobody receives another site's default certificate.

Step 5

Serve the full certificate chain

Point the server at the full chain rather than the leaf certificate alone: fullchain.pem for Let's Encrypt, or your certificate followed by the intermediate bundle for a commercial one. In a hosting panel, fill in the CA bundle or intermediate field. Reload the server and repeat the openssl s_client -showcerts test to confirm that more than one certificate is sent and verification returns 0.

Step 6

Enable TLS 1.2 and TLS 1.3

Set the server to offer TLS 1.2 and TLS 1.3 only, with ssl_protocols TLSv1.2 TLSv1.3 in nginx or SSLProtocol -all +TLSv1.2 +TLSv1.3 in Apache, and remove any hand-picked list of old ciphers copied from an outdated guide. Check that nginx's listen 443 line includes ssl. Behind a CDN, use a strict mode that validates the origin certificate, and make sure the origin accepts TLS 1.2 or later.

Step 7

Retest from outside your own network

Repeat the curl and openssl checks from a different machine, or use an online TLS checker, because your own browser may have cached intermediates. Test every hostname you fixed, then re-run the HTTP Error Audit so each URL is fetched again. Finally, set up expiry monitoring that alerts you a couple of weeks before any certificate runs out, since renewal failures are otherwise silent.

Keeping certificates healthy

Questions and answers

1. What does SSL handshake failed mean?

It means the browser or crawler and your server could not agree a secure connection, so no page was ever requested. The usual causes are an expired certificate, a certificate that does not list the hostname being visited, a missing intermediate certificate so the chain cannot be verified, or a server offering only old TLS versions. Behind Cloudflare, error 525 is the specific message for a failed handshake between Cloudflare and your own server rather than the visitor.

2. Why does my site work in my browser but the audit reports an SSL error?

The most common reason is a missing intermediate certificate. Desktop browsers often remember intermediates from other sites or fetch them automatically, so they cope, but crawlers, command-line tools and some mobile devices do not. Test with openssl s_client and the -showcerts option: if only one certificate is sent, configure the server with the full chain file. Another cause is a hostname, such as the bare domain, that you rarely visit yourself.

3. Does my SSL certificate need to cover both www and non-www?

Yes, if both addresses can be reached, which is almost always the case. The certificate is checked before any redirect happens, so a visitor typing the bare domain sees a warning even if the server would have redirected them to www. Issue one certificate listing both names, or separate certificates for each, and then redirect one to the other. Remember that a wildcard certificate does not cover the bare domain.

4. Why did my Let's Encrypt certificate expire when renewal is automatic?

Automatic renewal can fail silently. The validation request may be blocked by a firewall or a deny rule for the .well-known folder, an old IPv6 record may point at a previous server, the renewal timer may have been removed during a server change, or the certificate may have renewed without the web server being reloaded. Run certbot renew with the dry-run option to see the error, and add your own expiry monitoring.

5. How do I fix NET::ERR_CERT_COMMON_NAME_INVALID?

The certificate your server sent does not include the hostname in the address bar. Check the subject alternative names with openssl, and compare them with the address being visited. Either the certificate needs reissuing with the missing name, such as the bare domain or a subdomain, or the hostname is not attached to the right site on the server, so it receives the default certificate of another site. Fix whichever applies and test again.

6. What causes Cloudflare error 525 or 526?

Both are about the connection between Cloudflare and your origin server, not the visitor. A 525 means the TLS handshake with your origin failed, often because the origin is not listening for HTTPS on port 443 or only supports old protocols. A 526 appears when Cloudflare is set to validate the origin strictly and the origin certificate is expired, self-signed or issued for another name. Install a valid public or Cloudflare origin certificate on the server.

7. Which TLS versions should my server support?

For most public websites, enable TLS 1.2 and TLS 1.3 and disable everything older. TLS 1.0 and 1.1 are formally deprecated and modern browsers refuse them, so keeping them adds risk without helping real visitors. Disabling TLS 1.2 as well is usually too strict for now, because some crawlers, older devices and business systems still rely on it. Test the result with openssl using the tls1_2 and tls1_3 options, from a machine outside your own network.

Check every hostname for SSL failures

The HTTP Error Audit requests every URL in your crawl scope, records the status code and response time, follows redirects and flags anything outside the 200 range, including handshake failures that stop a page before any status code is sent.

Open HTTP Error Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All HTTP Error Fixes  ·  HTTPS Redirects  ·  Mixed Content  ·  HTTP Errors in Plesk and cPanel  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.