We are in the process of testing HAProxy 1.8.x with ALPN and H2 on some of our servers. We have default 502 and 503 errorfiles defined (ex. errorfile 503 /etc/haproxy/errors/503.http), but we've noticed that these errorfiles are not served to the user's browser when the error occurs (for instance, if the backend is down, a user should get the 503 errorfile).
Chrome returns "ERR_SPDY_PROTOCOL_ERROR", Curl [1] returns "curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)", and Firefox shows "The connection to <servername> was interrupted while the page was loading." With debug logging turned on, I can see that HAProxy is recognizing a 503 if the back-end server is down [2], but it doesn't seem to pass that error through to the client browser. If the backend is up and a 502 is generated, users do not receive the errorfile either. If we turn off H2 and drop back to HTTP/1.1, the errorfiles are displayed properly (though via HTTP/0.9) This has been observed in both 1.8.4 and 1.8.9. Our platform is Amazon Linux, using openssl-1.0.2k-12.109.amzn1.x86_64. Thanks in advance for any thoughts you might have - [1] Curl verbose (curl -vvvvI) output: * Trying <ipaddr>... * TCP_NODELAY set * Connected to <servername> (<ipaddr>) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH * successfully set certificate verify locations: * CAfile: /etc/ssl/cert.pem CApath: none * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Client hello (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Client hello (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 * ALPN, server accepted to use h2 * Server certificate: * subject: [removed] * start date: Mar 20 00:00:00 2017 GMT * expire date: Mar 24 12:00:00 2020 GMT * subjectAltName: host "<hostname>" matched cert's "<certname>" * issuer: C=US; O=DigiCert Inc; CN=DigiCert SHA2 Secure Server CA * SSL certificate verify ok. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x7fbded005400) > HEAD /libs/cq/core/content/welcome.html HTTP/2 > Host: <hostname> > User-Agent: curl/7.54.0 > Accept: */* > * Connection state changed (MAX_CONCURRENT_STREAMS updated)! * HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2) * Closing connection 0 * TLSv1.2 (OUT), TLS alert, Client hello (1): curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2) [2] haproxy[19803]: <ipaddr>:63832 [05/Jun/2018:15:36:24.202] incoming_https~ local_author_app_http/<NOSRV> 0/-1/-1/-1/0 503 1441 - - SCDN 3/1/0/0/0 0/0 "GET /libs/cq/core/content/welcome.html HTTP/1.1"

