Enabling HTTP/2 in Apache Tomcat: TLS, version requirements, and verification
Enable HTTP/2 in Apache Tomcat using the Http2Protocol connector, TLS, and Java 11+, then verify with curl and browser DevTools.
13 May 2026, 16:24 UTC

The problem: too many connections for too many small files
Your application loads, but the browser waterfall still shows dozens of connections and waiting gaps between small assets. That pattern usually points to HTTP/1.1 connection limits and head-of-line blocking, where one slow response stalls others sharing the same TCP connection.
Tomcat can serve HTTP/2 natively, which lets multiple requests and responses share one TLS connection. The takeaway: switching to Tomcat's Http2Protocol connector often reduces those round trips, but it is not a cleartext toggle. It requires Java 11 or newer, Tomcat 9.0.70 or later or any Tomcat 10 release, and a working TLS configuration.
Prerequisites before editing server.xml
- Java 11 or newer. Tomcat's HTTP/2 implementation relies on the JDK's HTTP/2 core libraries and ALPN. ALPN, or Application-Layer Protocol Negotiation, is the TLS extension that lets client and server agree on h2 during the handshake.
- Supported Tomcat version. Tomcat versions before 9.0.70 do not include org.apache.coyote.http2.Http2Protocol. Setting that class on an older release prevents startup.
- TLS is required. Tomcat's default HTTP/2 support negotiates over TLS only. Cleartext HTTP/2, known as h2c, is not enabled by default, so clients that cannot negotiate TLS fall back to HTTP/1.1.
Worked connector example
Edit $CATALINA_HOME/conf/server.xml. The file must be writable by the user account that runs Tomcat; otherwise use sudo and verify ownership afterward.
<Connector
port="8443"
protocol="org.apache.coyote.http2.Http2Protocol"
SSLEnabled="true"
scheme="https"
secure="true">
<SSLHostConfig
certificateVerification="none"
sslProtocol="TLSv1.2">
<Certificate
certificateKeystoreFile="/path/to/keystore.p12"
certificateKeystorePassword="changeit"
certificateKeystoreType="PKCS12"
certificateFile="/path/to/cert.pem"
certificateKeyFile="/path/to/key.pem"/>
</SSLHostConfig>
</Connector>
Replace /path/to/... and the placeholder password with values for your environment. certificateFile and certificateKeyFile are optional depending on your keystore type.
Run the restart command on the Tomcat host as the Tomcat user or with sudo:
$CATALINA_HOME/bin/catalina.sh start
# or
sudo systemctl restart tomcat
Expected check: Tomcat starts and the connector loads. Risks: an unsupported Tomcat version fails at startup because the Http2Protocol class is missing, and an invalid keystore path blocks all HTTPS traffic.
Verify the negotiation
Inspect the startup log from the Tomcat host:
tail -n 80 $CATALINA_HOME/logs/catalina.out
Look for a startup line referencing Http2Protocol. Exact wording varies by Tomcat version, so treat the absence of any matching line as a signal to revisit the connector class and version.
From a client with network access, run:
curl -I --http2 https://your-domain:8443/
Expected: a 200 response whose first line includes HTTP/2. If you use a self-signed certificate, curl may reject it; add --insecure only for temporary local testing, never for production verification.
In Chrome DevTools, open the Network tab, reload the page, and check the Protocol column for h2 on loaded resources.
Practical check: do not rely on a single curl result. ALPN negotiation can fail silently if a client or load balancer does not advertise h2, so confirm across multiple resources and repeat after any TLS change.
Trade-offs and limitations
TLS handshake overhead can make HTTP/2 slower than plain HTTP/1.1 on very low-latency local networks. HTTP/2 does not fix slow application code or database queries. Older clients fall back automatically, which helps compatibility but means you cannot assume every visitor gets h2. ALPN misconfiguration is a common silent failure: the connector starts, but clients never negotiate HTTP/2.
Rollback
Because this change edits server.xml, revert by replacing protocol="org.apache.coyote.http2.Http2Protocol" with protocol="org.apache.coyote.http11.Http11NioProtocol", saving the file, and restarting Tomcat. Keep a backup copy of server.xml before editing.
Closing checklist
- Run
java -versionand confirm 11 or later. - Confirm Tomcat is 9.0.70 or later, or a 10.x release.
- Back up server.xml, add the Http2Protocol connector with TLS, and restart.
- Verify with catalina.out, curl --http2, and DevTools Protocol column.
- If h2 never appears, check ALPN and TLS configuration before assuming the connector is at fault.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.