Enable HTTP/2 on Apache Tomcat 9 and 10 with TLS and ALPN
Configure Tomcat to negotiate HTTP/2 over HTTPS using the Http2Protocol connector, then verify ALPN negotiation and plan fallback for older clients.
17 Jul 2025, 00:37 UTC

Desired outcome
Configure Apache Tomcat to accept HTTP/2 connections over TLS so clients that support ALPN can negotiate HTTP/2, while older clients continue working over HTTP/1.1 on the same port.
Prerequisites
- Apache Tomcat 9.0.30 or later, or Tomcat 10.0.0 or later.
- A Java runtime with ALPN support. Tomcat 9 on Java 8 may require the ALPN boot classpath; Java 9 and later, including the Java 11+ runtime used by Tomcat 10, include ALPN support in the JDK.
- A TLS keystore in JKS or PKCS12 format for the connector.
- Write access to
$CATALINA_HOME/conf/server.xmland permission to restart the Tomcat service.
ALPN (Application-Layer Protocol Negotiation) is a TLS extension that lets the client and server agree on HTTP/2 during the handshake. $CATALINA_HOME is the Tomcat installation directory.
Configure the HTTP/2 connector
- Open
$CATALINA_HOME/conf/server.xmlon the server running Tomcat. - Add or replace an HTTPS connector using the HTTP/2 protocol handler:
<Connector
port="8443"
protocol="org.apache.coyote.http2.Http2Protocol"
maxThreads="200"
scheme="https"
secure="true"
SSLEnabled="true"
keystoreFile="/etc/tomcat/keystore.jks"
keystorePass="changeit"
clientAuth="false"
sslProtocol="TLS"/>
Run the edit as the user who owns the Tomcat installation, commonly tomcat or root depending on your package layout. Replace /etc/tomcat/keystore.jks and changeit with your keystore path and password.
- Save the file and restart Tomcat:
sudo systemctl restart tomcat
Risk: an incorrect keystore path, password, or missing ALPN provider can prevent Tomcat from starting. Back up server.xml before editing so you can restore the previous connector quickly.
Verify HTTP/2 negotiation
- From a client that can reach the server, run:
curl -I --http2 https://localhost:8443
Expected check: the first line should read HTTP/2 200. If you see HTTP/1.1 200, the client did not negotiate HTTP/2.
- Confirm ALPN directly with OpenSSL:
openssl s_client -connect localhost:8443 -alpn h2
Expected check: the output should show ALPN selecting h2. If ALPN is absent or empty, the JVM or connector configuration does not support HTTP/2 negotiation.
- Watch Tomcat startup logs while the service restarts. Look for connector initialization errors; a missing ALPN provider usually appears as a failure to initialize the HTTPS connector rather than a guaranteed success message.
Limitations and fallback behavior
- HTTP/2 is only used when the client offers it during TLS negotiation. Clients without ALPN automatically fall back to HTTP/1.1 on the same connector.
- A reverse proxy in front of Tomcat must also support ALPN and HTTP/2 to the client; otherwise end users will not see HTTP/2 even if Tomcat is configured correctly.
- Large request headers or bodies may need larger
maxHttpHeaderSizeormaxPostSizevalues to avoid 400 errors.
Rollback
Because editing server.xml changes server state, restore the previous connector or comment out the HTTP/2 connector and restart:
sudo systemctl restart tomcat
Verify that HTTPS still works over HTTP/1.1 with:
curl -I --http1.1 https://localhost:84430 replies
A thoughtful contribution can make all the difference. Be the first to share one.