28

I occasionally get the following 421 error:

Misdirected Request

The client needs a new connection for this request as the requested host name does not match the Server Name Indication (SNI) in use for this connection.

However, refreshing the browser clears the error and the page loads normally. The next time loading the page will not produce and error and as such the pattern seems pretty random. The only pattern I can see is that this may happen When I am redirecting a page using header("Location: " . $url);

I have a PositiveSSL Multi-Domain Certificate from Comodo. My servers are Apache on a shared web hosting service so I don't have access to the configuration.

I load pages from one domain and within the page are links to a second domain on the certificate.

Everything I've read regarding this error seems to point to this problem being related to this being a multi-domain certificate.

What I would like to know is if there is anything on the web page (php) coding side of things that can cause this (and can be fixed) or if it is a configuration error or possibly a server error and only my hosting service can fix it.

My hosting service has so far been unable to provide anything and requested calling back with the exact time it happens next so they can research it. Any help would be appreciated as I am not overly confident they can figure this out.

UPDATE Ok, almost a couple of years later and decided it was time to deal with it. I was able to get most of the problems resolved by removing my static domains which served images and javascript. However, I was still using a second domain for some of this content and Safari in particular was still giving me problems.

I did more research and came across another article that talks about it here. Exactly what @Kevin describes. The article confirmed that it happens in Safari. So taking the advice, I set about getting separate certificates for each domain. I am on a shared host (Webhostinghub) and discovered they now offer free SSL (AutoSSL) that auto renews. It sounded to good to be true. They set me up with 5 free certificates. So far so good. I may even try to re-enable the static domains to test. If this all works, I'll save $ to boot as a bonus and let my Comodo certificates expire in July.

mseifert
  • 459

7 Answers7

36

This is caused by the following sequence of events:

  1. The server and client both support and use HTTP/2.
  2. The client requests a page at foo.example.com.
  3. During TLS negotiation, the server presents a certificate which is valid for both foo.example.com and bar.example.com (and the client accepts it). This could be done with a wildcard certificate or a SAN certificate.
  4. The client reuses the connection to make a request for bar.example.com.
  5. The server is unable or unwilling to support cross-domain connection reuse (for example because you configured their SSL differently and Apache wants to force a TLS renegotiation), and serves HTTP 421.
  6. The client does not automatically retry with a new connection (see for example Chrome bug #546991, now fixed). The relevant RfC says that the client MAY retry, not that it SHOULD or MUST. Failing to retry is not particularly user-friendly, but might be desirable for a debugging tool or HTTP library.

Event #6 is out of your control, but depending on the server's software, #5 may be fixable. Consult your server's HTTP/2 documentation for more information on how and when it sends HTTP 421. Alternatively, you could issue separate certificates for each domain, but that creates more administrative overhead and may not be worth it. You could also turn off HTTP/2 entirely, but that's probably overkill in most cases.

Kevin
  • 546
2

Maybe this will be helpful to someone.

I got this error when I tried to change my apache virtual host configuration to HTTPS but only changed port from 80 to 443 and forgot to add

   SSLEngine on
   SSLCertificateFile "/opt/lampp/htdocs/localhost.crt"
   SSLCertificateKeyFile "/opt/lampp/htdocs/localhost.key"

Configuration causing error 421:

<VirtualHost mydoamin.local:443>   <-- fistly I 
       DocumentRoot "/opt/lampp/htdocs/mydomain/"
       ServerName www.mydomain.local
</VirtualHost>

The correct configuration:

<VirtualHost mydoamin.local:443>
       DocumentRoot "/opt/lampp/htdocs/mydomain/"
       ServerName www.mydomain.local
       SSLEngine on
       SSLCertificateFile "/opt/lampp/htdocs/localhost.crt"
       SSLCertificateKeyFile "/opt/lampp/htdocs/localhost.key"
</VirtualHost>
1

We observed the same issue with Safari (Desktop and iPhone) on some websites using Debian 10 with Apache.

Software:

  • Debian 10
  • Apache2 2.4.38-3+deb10u3 with HTTP/2
  • PHP 7.3.14-1~deb10u1 with php-fpm

Domains:

  • www.example.com
  • a.example.com
  • b.example.com
  • all domains are pointing to the same DocumentRoot

Certificate:

  • One certificate for all used domains
  • Issuer is DFN PKI

The solution was quite easy but it took much effort to find it. At the end it was trial an error.

Configuration causing error 421:

    # in /etc/apache2/site-enabled/www.example.com.conf
    SSLCertificateFile      /etc/apache2/ssl/www.example.com/cert-123.pem
    SSLCertificateKeyFile   /etc/apache2/ssl/www.example.com/www.example.com.key

    # in /etc/apache2/site-enabled/a.example.com.conf
    SSLCertificateFile      /etc/apache2/ssl/a.example.com/cert-123.pem
    SSLCertificateKeyFile   /etc/apache2/ssl/a.example.com/www.example.com.key

    # in /etc/apache2/site-enabled/b.example.com.conf
    SSLCertificateFile      /etc/apache2/ssl/b.example.com/cert-123.pem
    SSLCertificateKeyFile   /etc/apache2/ssl/b.example.com/www.example.com.key

Working configuration:

    # in /etc/apache2/site-enabled/www.example.com.conf
    SSLCertificateFile      /etc/apache2/ssl/www.example.com/cert-123.pem
    SSLCertificateKeyFile   /etc/apache2/ssl/www.example.com/www.example.com.key

    # in /etc/apache2/site-enabled/a.example.com.conf
    SSLCertificateFile      /etc/apache2/ssl/www.example.com/cert-123.pem
    SSLCertificateKeyFile   /etc/apache2/ssl/www.example.com/www.example.com.key

    # in /etc/apache2/site-enabled/b.example.com.conf
    SSLCertificateFile      /etc/apache2/ssl/www.example.com/cert-123.pem
    SSLCertificateKeyFile   /etc/apache2/ssl/www.example.com/www.example.com.key

Solution (in our case): It's not allowed to copy the same certificate and private key to different locations!

Before we copied the certificate to a VirtualHost specific directory. This results in the Misdirected Request behaviour only with Safari.

Unfortunately, I cannot explain you, why :-( (Apache2 bug? Safari bug? Safari feature?)

0

It is only an issue on Safari, and due to the SSL certificate.

Many hosting providers give free certificates that are shared, and thus "www.site.com" and "site.com" will both share the same certificate.

When you setup your server to redirect all "site.com" requests to "www.site.com", this is where the issue occurs, as they both share the same certificate and Safari sees them as two different pages.

The only solution is to get a different certificate for each subdomain, something most hosting providers are a bit reluctant to do when letting you share these free certificates. Also, there is nothing wrong with sharing a certificate, and Safari should allow it.

In the meantime, harass Apple to fix the Safari bug.

0

I had the same issue and the problem was with the server name, it was wrong

WRONG CONFIG:

<VirtualHost domain.name:443>
ServerName domain.name2 # SERVER NAME NOT IDENTICAL TO VIRTUALHOST 
DocumentRoot &quot;/documents/&quot;
SSLEngine on
SSLCertificateFile &quot;/etc/apache2/ssl/domain.name.crt&quot;
SSLCertificateKeyFile &quot;/etc/apache2/ssl/domain.name.key&quot;

</VirtualHost>

The ServerName value must be the same as VirtualHost

When I changed to:

<VirtualHost domain.name:443>
ServerName domain.name
DocumentRoot &quot;/documents/&quot;
SSLEngine on
SSLCertificateFile &quot;/etc/apache2/ssl/domain.name.crt&quot;
SSLCertificateKeyFile &quot;/etc/apache2/ssl/domain.name.key&quot;

</VirtualHost>

It all worked, hope it helps.

talsibony
  • 153
0

Tl;dr: Regenerating the certificates without the wildcard variant solved my issue.

Detailed answer: I had a similar issue on my server. Tried to do the 302 redirection from my main domain to a subdomain using this URL shortener mechanism https://github.com/hindus-pl/own-shortener which relies on sending "Location" header with PHP script.

I checked which certificates were used when accessing domain.com and sub.domain.com and they were different on Chrome/Windows.

Retrying this on Safari/Mac proved that the same (main domain) cert was used for both sites.

The culprit here was a way how the certificates (from Let's Encrypt) were generated. In my case both included a wildcard variant of the domain they were generated for, so there were 2 "DNS Name" entries. For main domain, it was:

  • domain.com
  • *.domain.com

And for subdomain:

  • sub.domain.com
  • *.sub.domain.com

This is what caused the Safari browser to reuse the same certificate when executing HTTP 302 redirection on HTTP/2 enabled server and caused the error.

Other browsers browser were correctly retrieving the subdomain certificate and using it so no error was raised.

Thanks for Kevin for listing this as one of the possibilities, I wanted to add this as a comment but I decided to elaborate this case a little bit further :) I hope no one minds.

Mark
  • 101
-1

I had the same issue. Switching to two single-slot SSLs did the trick.

Olivier
  • 11