Detailed Description of the Problem
When the backend is h2, h2c requests is not processed correctly.
Expected Behavior
When the frontend is marked with proto h1, a 200 response should be returned;
If the frontend is not marked as "proto", it is best to return 101 and upgrade the connection to handle binary bodies;
I'm not sure what response should be generated if I send an H2C request to the frontend, and when the frontend is marked with proto h2.
Steps to Reproduce the Behavior
- haproxy -f h2c.cfg
- curl --http2 http://127.0.0.1:8082 -i
- curl --http2 http://127.0.0.1:8083 -i
Do you have any idea what may have caused this?
It seemd the commit 8dd49df is to blame.
Do you have an idea how to solve the issue?
No response
What is your configuration?
# h2c.cfg
defaults
mode http
timeout client 1s
timeout connect 1s
timeout server 1s
log stderr local0
option httplog
listen step1
bind 127.0.0.1:8082
server _ 127.0.0.1:10002 proto h2
listen step1_h1
bind 127.0.0.1:8083 proto h1
server _ 127.0.0.1:10002 proto h2
listen step1_h2
bind 127.0.0.1:8084 proto h2
server _ 127.0.0.1:10002 proto h2
listen step2
bind 127.0.0.1:10002 proto h2
server _ 127.0.0.1:10003 proto h1
frontend step3
bind 127.0.0.1:10003 proto h1
http-request return content-type text/plain string "hello, world!\n"
Output of haproxy -vv
HAProxy version 3.4-dev13-e8c9aa-39 2026/05/25 - https://haproxy.org/
Status: development branch - not safe for use in production.
Known bugs: https://github.com/haproxy/haproxy/issues?q=is:issue+is:open
Running on: Linux 7.0.9-205.fc44.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 21 16:31:48 UTC 2026 x86_64
Build options :
TARGET = linux-glibc
CC = clang
CFLAGS = -O2 -g -fwrapv -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -flto=auto -ffat-lto-objects -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security
OPTIONS = USE_OPENSSL_AWSLC=1 USE_LUA=1 USE_QUIC=1 USE_PROMEX=1 USE_PCRE2=1 USE_PCRE2_JIT=1
DEBUG =
Feature list : -51DEGREES +ACCEPT4 +ACME +BACKTRACE -CLOSEFROM +CPU_AFFINITY +CRYPT_H -DEVICEATLAS +DL -ECH -ENGINE +EPOLL -EVPORTS +GETADDRINFO +HAVE_TCP_MD5SIG -KQUEUE +KTLS -LIBATOMIC +LIBCRYPT +LINUX_CAP +LINUX_SPLICE +LINUX_TPROXY +LUA +MATH -MEMORY_PROFILING +NETFILTER +NS -OBSOLETE_LINKER +OPENSSL +OPENSSL_AWSLC -OPENSSL_WOLFSSL -OT -PCRE +PCRE2 +PCRE2_JIT -PCRE_JIT +POLL +PRCTL -PROCCTL +PROMEX -PTHREAD_EMULATION +QUIC -QUIC_OPENSSL_COMPAT +RT +SHM_OPEN +SLZ +SSL -STATIC_PCRE -STATIC_PCRE2 +TFO +THREAD +THREAD_DUMP +TPROXY +TRACE -WURFL -ZLIB
Detected feature list : +HAVE_WORKING_TCP_MD5SIG
Default settings :
bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Built with multi-threading support (MAX_TGROUPS=32, MAX_THREADS=1024, default=2).
Built with SSL library version : OpenSSL 1.1.1 (compatible; AWS-LC 1.73.0)
Running on SSL library version : AWS-LC 1.73.0
SSL library supports TLS extensions : yes
SSL library supports SNI : yes
SSL library FIPS mode : no
SSL library default verify directory : /etc/ssl/certs
SSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
QUIC: connection sock-per-conn mode support : yes
QUIC: GSO emission support : yes
Built with Lua version : Lua 5.4.8
Built with the Prometheus exporter as a service
Built with network namespace support.
Built with libslz for stateless compression.
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Built with PCRE2 version : 10.47 2025-10-21
PCRE2 library supports JIT : yes
Encrypted password support via crypt(3): yes
Built with clang compiler version 22.1.5 (Fedora 22.1.5-1.fc44)
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.
Available multiplexer protocols :
(protocols marked as <default> cannot be specified using 'proto' keyword)
quic : mode=HTTP side=FE|BE mux=QUIC flags=HTX|NO_UPG|FRAMED
qmux : mode=HTTP side=FE|BE mux=QMUX flags=HTX|NO_UPG
h2 : mode=HTTP side=FE|BE mux=H2 flags=HTX|HOL_RISK|NO_UPG
h1 : mode=HTTP side=FE|BE mux=H1 flags=HTX|NO_UPG
<default> : mode=HTTP side=FE|BE mux=H1 flags=HTX
fcgi : mode=HTTP side=BE mux=FCGI flags=HTX|HOL_RISK|NO_UPG
spop : mode=SPOP side=BE mux=SPOP flags=HOL_RISK|NO_UPG
<default> : mode=SPOP side=BE mux=SPOP flags=HOL_RISK|NO_UPG
none : mode=TCP side=FE|BE mux=PASS flags=NO_UPG
<default> : mode=TCP side=FE|BE mux=PASS flags=
Available services : prometheus-exporter
Available filters :
[BWLIM] bwlim-in
[BWLIM] bwlim-out
[CACHE] cache
[COMP] comp-req
[COMP] comp-res
[COMP] compression
[FCGI] fcgi-app
[SPOE] spoe
[TRACE] trace
Last Outputs and Backtraces
[NOTICE] (266210) : Automatically setting global.maxconn to 262131.
<134>May 26 12:04:44 haproxy[266210]: 127.0.0.1:39850 [26/May/2026:12:04:44.326] step3 step3/<NOSRV> 0/-1/-1/-1/0 200 0 - - LR-- 3/1/0/0/0 0/0 "GET / HTTP/1.1"
<134>May 26 12:04:44 haproxy[266210]: 127.0.0.1:57902 [26/May/2026:12:04:44.325] step2 step2/_ 0/0/1/0/1 200 86 - - ---- 3/1/0/0/0 0/0 "GET https://127.0.0.1:8082/ HTTP/2.0"
<134>May 26 12:04:44 haproxy[266210]: 127.0.0.1:41180 [26/May/2026:12:04:44.324] step1 step1/_ 0/0/1/1/2 101 108 - - SD-- 3/1/0/0/0 0/0 "GET / HTTP/1.1"
<134>May 26 12:04:49 haproxy[266210]: 127.0.0.1:39864 [26/May/2026:12:04:49.668] step3 step3/<NOSRV> 0/-1/-1/-1/0 200 0 - - LR-- 3/1/0/0/0 0/0 "GET / HTTP/1.1"
<134>May 26 12:04:49 haproxy[266210]: 127.0.0.1:57910 [26/May/2026:12:04:49.667] step2 step2/_ 0/0/1/0/1 200 86 - - ---- 3/1/0/0/0 0/0 "GET https://127.0.0.1:8083/ HTTP/2.0"
<134>May 26 12:04:49 haproxy[266210]: 127.0.0.1:43096 [26/May/2026:12:04:49.666] step1_h1 step1_h1/_ 0/0/1/1/2 101 108 - - SD-- 3/1/0/0/0 0/0 "GET / HTTP/1.1"
HTTP/1.1 101 Switching Protocols
content-type: text/plain
content-length: 14
connection: upgrade
curl: (16) Remote peer returned unexpected data while we expected SETTINGS frame. Perhaps, peer does not support HTTP/2 properly.
Additional Information
No response
Detailed Description of the Problem
When the backend is h2, h2c requests is not processed correctly.
Expected Behavior
When the frontend is marked with
proto h1, a 200 response should be returned;If the frontend is not marked as "proto", it is best to return 101 and upgrade the connection to handle binary bodies;
I'm not sure what response should be generated if I send an H2C request to the frontend, and when the frontend is marked with
proto h2.Steps to Reproduce the Behavior
Do you have any idea what may have caused this?
It seemd the commit 8dd49df is to blame.
Do you have an idea how to solve the issue?
No response
What is your configuration?
Output of
haproxy -vvLast Outputs and Backtraces
Additional Information
No response