421 is returned when the browser tries to reuse the connection for another site. This is allowed under HTTP/2 to save the cost of opening another connection as, in most cases, it is better to use fewer connections under HTTP/2.
The browser should only reuse a connection which maps to the same IP address and where the certificate used covers both sites (which is the case for your three sites).
Despite these conditions, occasionally the browser will try to reuse a connection when it shouldn’t. The main case for Apache is if different SSL/TLS settings are set up for each vhost. Looking at ssllabs.com for each of your three domains there setup looks the same so finding it difficult to see why Apache is returning this. You should get in touch with your hosting providing and ask them to verify this.
In these cases Firefox will see the 421 response, establish a new connection and request the resource again. Though, unlike a 301or 302 it looks like this will not show as a separate request in developer tools.
The alternatives to fix this are:
- Get the hosting provider to identify the cause and allow the connections to be reused.
- Use different certs for each domain (so the browser won’t try to reuse the connection).
- Use different IP address for the other domains even if they map to the same server (so the browser won’t try to reuse the connection).
- Stop using http/2 - which seems a shame since it’s usually gives a good performance gain.
- Stop using other domains, at least for HTTP/2.
I think you should seriously look at the last one. The benefit of using other domains (called sharding) is often overstated in my opinion for HTTP/1 and should not be necessary under HTTP/2.
Sharding is done for two reasons:
- To allow 6 more connections under HTTP/1.1 as browsers typical max out at 6 simultaneous connections per domain. However, unless those 7th, 8th...etc connections are used a lot the cost of setting them up may not be worthwhile. And under HTTP/2 the limit is much higher (usually at least simultaneous 100 streams per connection).
- Cookie-less domains to save on request sizes. But under HTTP/2, HTTP headers are compressed so you are less worried about this (and again in my opinion the value of this was overstated - how big are cookies really.).
Looking at webpagetest for your homepage, you are loading the main page over the www domain, and then 6 assets over one static sub domain and 6 assets over the next subdomain and the a few more over each:
Here you can see the true cost of your 421s as nearly every connection has to be restablished with a connect and SSL negotiation. Ignoring this for a bit you can see that, yes iyou are downloading more than 6 resources at the same time over your two static subdomains. So if this was an HTTP/1.1 connection you would benefit from breaking the 6 connection limit for a bit. But you are also wasting the www connection which is idle after the first request. This is made more obvious from the Connection View:
So you could get rid of one of those subdomains and serve those assets for the www domain to getting utilization out of that first connection.
For HTTP/2 you can get rid of the other domain too as shouldn’t be needed. You can then either serve different results to HTTP/2 and HTTP/1.1 users but that is complicated, all the main browsers support HTTP/2 and for 24 requests in total it’s not even going to be much of a performance drag going to one domain for those that don’t.
In summary stop sharding to cookieless domains unless you have a real good reason to, as from a quick look at your home page anyway, it is not helping your performance and while you are hitting this 421 issue you are hindering it considerably.