Diagnosing HTTP/2 Enablement Issues in Tomcat 9+ with the NIO2 Connector
When Tomcat reports “Failed to accept HTTP/2 connection: ALPN not available” or clients cannot upgrade, this guide walks through common causes, checks, and fixes to get HTTP/2 working on Tomcat 9+.
13 Nov 2025, 17:08 UTC

Recognizable Condition
Clients connect to https://…:8443 and receive a 400 Bad Request or the Tomcat log contains:
2026-10-14 18:01:44,123 ERROR [http-nio-8443-exec-1] org.apache.coyote.http11.Http11Nio2Protocol - Failed to accept HTTP/2 connection: ALPN not available
Despite the connector being configured for HTTP/2, the upgrade never occurs. The goal is to determine why.
Common Causes & Diagnostic Table
| Cause | Diagnostic Check | Expected Log |
|---|---|---|
| Missing ALPN provider on the JVM classpath | Check if alpn-boot-*.jar is present or if the JDK has built‑in ALPN | "ALPN not available" error |
| Connector not upgraded to HTTP/2 | Verify <upgradeProtocol> entry in server.xml | "Failed to accept HTTP/2 connection" |
| TLS protocol limited to TLSv1.0/1.1 | Inspect sslProtocol or sslEnabledProtocols | "Failed to accept HTTP/2 connection" |
| Firewall blocks port 8443 | Run telnet 127.0.0.1 8443 or nc -vz | No TLS handshake, connection reset |
Ordered Checks
- Verify Connector Configuration
In
conf/server.xmlconfirm the connector uses the NIO2 protocol and includes the HTTP/2 upgrade protocol:<Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol" maxThreads="200" scheme="https" secure="true" SSLEnabled="true" sslProtocol="TLS" keyAlias="tomcat" keyPass="changeit" keyStoreFile="/path/to/keystore.p12" keyStorePass="changeit" keyStoreType="PKCS12" clientAuth="false" sslEnabledProtocols="TLSv1.2,TLSv1.3" org.apache.coyote.http2.Http2Protocol >Missing the
<upgradeProtocol>tag will prevent HTTP/2 negotiation. - Check ALPN Availability
Run:
java -jar alpn-boot-version.jar -verboseIf the JVM is 8u261+ or 9+, ALPN may already be built‑in. Verify by inspecting
java -XshowSettings:properties -versionforjdk.http2.provideror by checking the log forALPN not available. - Validate TLS Protocols
HTTP/2 requires TLSv1.2 or higher. Ensure the connector’s
sslEnabledProtocolsincludes them. Run:openssl s_client -connect localhost:8443 -tls1_2A successful handshake indicates the server accepts TLSv1.2.
- Test the Upgrade Path
From a client that supports HTTP/2 (modern browsers or
curl7.62+), issue:curl -I --http2 https://localhost:8443/Expect a response line like
HTTP/2 200. If the status line showsHTTP/1.1, the upgrade failed. - Check Firewall / Network Filters
Verify that port 8443 is reachable from the client machine:
telnet localhost 8443 # or nc -vz localhost 8443Connection timeouts or refusals point to a network block.
Fixes Tied to Findings
- ALPN Provider Missing
Download the appropriate
alpn-bootjar for your JDK and place it in$CATALINA_HOME/libor add it to the JVM classpath:java -cp alpn-boot-version.jar -jar bootstrap.jarRestart Tomcat and confirm the log no longer shows the ALPN error.
- Connector Not Upgraded
Add or correct the
<upgradeProtocol>entry as shown above. Restart Tomcat. - TLS Version Too Low
Update
sslEnabledProtocolstoTLSv1.2,TLSv1.3or remove the attribute to let Tomcat default to the JDK’s enabled protocols. Restart. - Firewall Blocking Port
Open the port in the host firewall (e.g.,
ufw allow 8443/tcporiptables -A INPUT -p tcp --dport 8443 -j ACCEPT). Re‑run the connectivity test. - Client Compatibility
Ensure the client supports HTTP/2. If using older browsers, plan for graceful fallback to HTTP/1.1 by keeping the upgrade protocol optional.
Escalation Criteria
If after applying the above fixes the server still logs ALPN not available or clients cannot upgrade, consider:
- Verify that the JDK version supports ALPN natively (Java 9+). If using Java 8, ensure the ALPN jar matches the exact JDK build.
- Check for classpath conflicts: another library may provide a conflicting ALPN implementation. Use
java -verbose:classto trace the loading oforg.eclipse.jetty.alpn.ALPNor similar classes. - Inspect the
catalina.outlog for stack traces that reference the servlet container’s HTTP/2 module. A missingorg.apache.coyote.http2.Http2Protocolclass indicates the module wasn’t packaged. - Consult the Tomcat issue tracker or community mailing list for known bugs in the specific Tomcat version (e.g., 9.0.89 had a regression with ALPN on OpenJDK 11).
Practical Verification Checklist
- Restart Tomcat after changes.
- Run
curl -I --http2 https://localhost:8443/and confirmHTTP/2 200in the response line. - Look for no
ALPN not availableentries incatalina.out. - Verify
openssl s_client -connect localhost:8443 -tls1_2succeeds.
By following this step‑by‑step diagnostic path you can isolate the root cause of HTTP/2 failure in Tomcat 9+ and apply the appropriate fix, ensuring secure, multiplexed connections for modern web clients.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.