# Wrong backend selected with SNI when using HTTP/2

**URL:** <https://discourse.haproxy.org/t/wrong-backend-selected-with-sni-when-using-http-2/7748>\
**Category:** Help!\
**Created:** [June 14, 2022, 8:14am UTC](https://discourse.haproxy.org/t/wrong-backend-selected-with-sni-when-using-http-2/7748 "2022-06-14T08:14:38Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![rradutiu](https://avatars.discourse-cdn.com/v4/letter/r/c57346/32.png) [@rradutiu](https://discourse.haproxy.org/u/rradutiu)\
**Post date:** [June 14, 2022, 8:14am UTC](https://discourse.haproxy.org/t/wrong-backend-selected-with-sni-when-using-http-2/7748/1 "2022-06-14T08:14:38Z")

</div>

When I activate http/2 using “alpn h2,http”, the backend selection fails. I have a wildcard certificate and select the backends based on SNI. Here is the relevant section of haproxy.cfg (haproxy version :2.0.13-2ubuntu0.5 2022/03/02)  
defaults  
log global  
mode http  
option forwardfor  
option http-keep-alive  
option redispatch  
timeout check 5s  
timeout client 5s  
timeout connect 5s  
timeout server 16m  
timeout tunnel 16m  
timeout http-request 5s  
timeout http-keep-alive 15s  
frontend https  
bind :443 ssl crt /etc/haproxy/ssl alpn h2,http/1.1  
use\_backend onlyoffice if { ssl\_fc\_sni [onlyoffice.sampledomain.com](http://onlyoffice.sampledomain.com) }  
use\_backend alfresco if { ssl\_fc\_sni [alfresco.sampledomain.com](http://alfresco.sampledomain.com) }  
The browsers (Edge, Firefox) show (in developer tools) that requests are made to  
GET [https://onlyoffice.sampledomain.com/OfficeWeb/apps/api/documents/api.js](https://onlyoffice.sampledomain.com/OfficeWeb/apps/api/documents/api.js)  
with response code 404 and request headers:  
Accept  
_/_  
Accept-Encoding  
gzip, deflate, br  
Accept-Language  
en-US,en;q=0.5  
Cache-Control  
no-cache  
Connection  
keep-alive  
DNT  
1  
Host  
[onlyoffice.sampledomain.com](http://onlyoffice.sampledomain.com)  
Pragma  
no-cache  
Referer  
[https://alfresco.sampledomain.com/](https://alfresco.sampledomain.com/)  
Sec-Fetch-Dest  
script  
Sec-Fetch-Mode  
no-cors  
Sec-Fetch-Site  
same-site  
TE  
trailers  
User-Agent  
Mozilla/5.0 (X11; Ubuntu; Linux x86\_64; rv:101.0) Gecko/20100101 Firefox/101.0  
In haproxy.log I have:  
Jun 14 11:08:42 dd2 haproxy[161556]: 127.0.0.1:53856 [14/Jun/2022:11:08:42.352] https~ alfresco/alfresco 0/0/69/37/106 404 942 - - ---- 1/1/1/1/0 0/0 {0,"",0} “GET /OfficeWeb/apps/api/documents/api.js HTTP/2.0”  
If I remove alpn h2, the request goes to the right backend:  
Jun 14 11:10:13 dd2 haproxy[162131]: 127.0.0.1:34712 [14/Jun/2022:11:10:13.709] https~ onlyoffice/onlyoffice 11/0/31/31/73 302 371 - - ---- 3/3/0/0/0 0/0 {0,"",0} “GET /OfficeWeb/apps/a  
pi/documents/api.js HTTP/1.1”  
Can someone explain what’s going on? Both Firefox and Edge show the same behavior.

---

<div class="post-metadata">

**Author:** ![Markus](https://avatars.discourse-cdn.com/v4/letter/m/b782af/32.png) [@Markus](https://discourse.haproxy.org/u/Markus)\
**Post date:** [June 14, 2022, 1:46pm UTC](https://discourse.haproxy.org/t/wrong-backend-selected-with-sni-when-using-http-2/7748/2 "2022-06-14T13:46:15Z")

</div>

i have the same. a ssl certificate with multiple domains (ok, no wildcard, but that should not matter)  
i use the config

```auto
bind 12.34.56.78:443 ssl crt /opt/haproxy/haproxy.ssl.crt crt /opt/haproxy/domain.pem alpn h2,http/1.1
capture request header Host len 32
use_backend server1 if { hdr(host) - domain1.com }
use_backend server2 if { hdr(host) - domain2.com }

```

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [June 14, 2022, 3:37pm UTC](https://discourse.haproxy.org/t/wrong-backend-selected-with-sni-when-using-http-2/7748/3 "2022-06-14T15:37:37Z")

</div>

You must not have overlapping certificates (across backends) when you use SNI based routing.

This is because when a browser connects in H2 to a HTTPS server with a wildcard/SAN certificate covering different backends, the browser will keep using that HTTPS connection available to it because it will assume that the connection can be used for everything the certificate would be valid for. And SNI is a field in the SSL handshake (therefor once only at the begging of the SSL session), it’s not something that is available or updated per transaction (as opposed to the Host header in HTTP).

---

<div class="post-metadata">

**Author:** ![rradutiu](https://avatars.discourse-cdn.com/v4/letter/r/c57346/32.png) [@rradutiu](https://discourse.haproxy.org/u/rradutiu)\
**Post date:** [June 14, 2022, 3:45pm UTC](https://discourse.haproxy.org/t/wrong-backend-selected-with-sni-when-using-http-2/7748/4 "2022-06-14T15:45:23Z")

</div>

I have investigated further using tcpdump and the browser is reusing the same tcp connection - this is indeed the reason why SNI selection fails. This (connection coalescing) is part of HTTP/2 standard (I was not aware until now). The solution to use the host header for backend selection works fine.  
I wonder if I could return a 421 error code (misdirected request) each time the SNI does not match the host header and keep using SNI. It would probably work but using just the host header looks cleaner.

---

<div class="post-metadata">

**Author:** ![lukastribus](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@lukastribus](https://discourse.haproxy.org/u/lukastribus)\
**Post date:** [June 14, 2022, 4:01pm UTC](https://discourse.haproxy.org/t/wrong-backend-selected-with-sni-when-using-http-2/7748/5 "2022-06-14T16:01:25Z")

</div>

In this particular configuration, using `ssl_fc_sni` doesn’t not make any sense at all. Only when using passthrough you are forced to use SNI based routing, but it should be avoided at all times.

---

<div class="post-metadata">

**Author:** ![Rickard\_505](https://avatars.discourse-cdn.com/v4/letter/r/5f9b8f/32.png) [@Rickard\_505](https://discourse.haproxy.org/u/Rickard_505)\
**Post date:** [June 17, 2022, 9:37am UTC](https://discourse.haproxy.org/t/wrong-backend-selected-with-sni-when-using-http-2/7748/6 "2022-06-17T09:37:12Z")

</div>

I use two frontends and a passthru backend for this (works perfectly), by something like this  
this because i have Websocket traffic. (DDP)

> <https://serverfault.com/questions/1093592/haproxy-sni-ssl-pass-through-or-termination>
