Last updated: 2026-02-11
Tomcat TLS/SSL Configuration Guide
This guide provides recommended TLS/SSL settings for Apache Tomcat. Tomcat supports TLS through two implementations: the default Java JSSE connector and the OpenSSL-based connector (via Tomcat Native/APR). This guide covers both approaches.
Prerequisites
- Tomcat 9.0.31 or later, or Tomcat 10+ (for TLS 1.3 support)
- Java 11 or later (for TLS 1.3 support in JSSE mode)
- For OpenSSL mode: Tomcat Native 1.2.23+ and OpenSSL 1.1.1+
- A valid SSL/TLS certificate
Certificate Formats
Tomcat supports different certificate formats depending on the connector type:
- JSSE (Java) -- Uses Java keystore (JKS/PKCS12) or PEM files (Tomcat 9.0.13+)
- OpenSSL/APR -- Uses PEM files
To create a PKCS12 keystore from PEM files:
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name tomcat
JSSE Connector (Default)
Configure TLS in the <Connector> element within server.xml ($CATALINA_HOME/conf/server.xml). The JSSE connector uses Java cipher suite names.
Protocol Versions
Restrict to TLS 1.2 and TLS 1.3:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig protocols="TLSv1.2+TLSv1.3">
<!-- certificate and cipher configuration here -->
</SSLHostConfig>
</Connector>
Cipher Suites (Java Names)
Use only strong AEAD cipher suites with ECDHE key exchange. Java uses its own cipher naming convention:
<SSLHostConfig protocols="TLSv1.2+TLSv1.3"
ciphers="TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
honorCipherOrder="false">
Note: All ChaCha20-Poly1305 ciphers (TLS_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, and TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) require Java 12+. On Java 11, omit all three and use only the AES-GCM ciphers.
Certificate Configuration (Keystore)
Using a PKCS12 keystore:
<SSLHostConfig>
<Certificate certificateKeystoreFile="/etc/tomcat/ssl/keystore.p12"
certificateKeystorePassword="changeit"
certificateKeystoreType="PKCS12" />
</SSLHostConfig>
Certificate Configuration (PEM Files)
Tomcat 9.0.13+ supports PEM files directly with the JSSE connector:
<SSLHostConfig>
<Certificate certificateFile="/etc/tomcat/ssl/cert.pem"
certificateKeyFile="/etc/tomcat/ssl/privkey.pem"
certificateChainFile="/etc/tomcat/ssl/chain.pem" />
</SSLHostConfig>
OpenSSL Connector (APR/Tomcat Native)
If Tomcat Native is installed, you can use the OpenSSL implementation for potentially better performance. This uses OpenSSL cipher names (same as Nginx/Apache).
<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig protocols="TLSv1.2+TLSv1.3"
ciphers="ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305"
honorCipherOrder="false">
<Certificate certificateFile="/etc/tomcat/ssl/cert.pem"
certificateKeyFile="/etc/tomcat/ssl/privkey.pem"
certificateChainFile="/etc/tomcat/ssl/chain.pem" />
</SSLHostConfig>
</Connector>
Note: Http11AprProtocol was removed in Tomcat 10.1+ (Debian 12, Ubuntu 24.04). On Tomcat 10.1+, use Http11NioProtocol with sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation" instead.
OCSP Stapling
Tomcat does not enable OCSP stapling by default. To enable it (Java 8u202+ or Java 11+), add these JVM flags to your startup options:
-Djdk.tls.server.enableStatusRequestExtension=true
-Dcom.sun.net.ssl.checkRevocation=true
HSTS and HTTPS Redirect
Tomcat does not add HSTS headers automatically. Configure the HttpHeaderSecurity filter in web.xml:
<filter>
<filter-name>httpHeaderSecurity</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<init-param>
<param-name>hstsEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>hstsMaxAgeSeconds</param-name>
<param-value>63072000</param-value>
</init-param>
<init-param>
<param-name>hstsIncludeSubDomains</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>httpHeaderSecurity</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
To redirect HTTP to HTTPS, add to web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>Secure</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
Complete Configuration Example (JSSE with PEM)
<!-- On Debian/Ubuntu, config is /etc/tomcat9/server.xml (or tomcat10); use systemctl restart tomcat9 -->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<!-- Note: ChaCha20 ciphers (CHACHA20_POLY1305) require Java 12+; on Java 11, omit them -->
<SSLHostConfig protocols="TLSv1.2+TLSv1.3"
ciphers="TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
honorCipherOrder="false">
<Certificate certificateFile="/etc/tomcat/ssl/cert.pem"
certificateKeyFile="/etc/tomcat/ssl/privkey.pem"
certificateChainFile="/etc/tomcat/ssl/chain.pem" />
</SSLHostConfig>
</Connector>
Verification
Restart Tomcat after making changes:
$CATALINA_HOME/bin/shutdown.sh
$CATALINA_HOME/bin/startup.sh
Path note: On Debian/Ubuntu, Tomcat is managed as a system service — use
systemctl restart tomcat9(ortomcat10). The config file is at/etc/tomcat9/server.xmlrather than$CATALINA_HOME/conf/server.xml.
Test the TLS connection:
openssl s_client -connect localhost:8443 -tls1_2
openssl s_client -connect localhost:8443 -tls1_3
Check which cipher suites are available from the Java runtime:
$JAVA_HOME/bin/jrunscript -e "java.util.Arrays.asList(javax.net.ssl.SSLContext.getDefault().createSSLEngine().getSupportedCipherSuites()).stream().forEach(println)"
Test your configuration externally using Qualys SSL Labs at https://www.ssllabs.com/ssltest/.