An HTTPS connector on 8443 that still negotiates TLSv1.0 or TLSv1.1 is active downgrade surface. Clients that can force TLSv1.0 can exploit protocol-level weaknesses, and ciphers that exist only to support legacy protocols weaken posture for every client. The fix has two parts: restrict the protocol list to TLSv1.2 and TLSv1.3, and prune the cipher list so weak suites are not offered.

This is a configuration change, not a runtime incident, but it has runtime consequences. A misconfigured SSLHostConfig prevents the connector from starting. A Tomcat upgrade can silently re-enable TLSv1.3 ciphers you intended to exclude. The procedure covers the version split between Tomcat 8.5/9 (where sslEnabledProtocols is deprecated but functional) and Tomcat 10/11 (where it is removed), the cipher attribute split in 9.0.115/10.1.52/11.0.18, and external verification.

Prerequisites

  • Tomcat 8.5 or newer. Tomcat 7.x and below use a different SSL model and are long past end of life.
  • Write access to $CATALINA_BASE/conf/server.xml and a way to restart Tomcat.
  • openssl and nmap on a host that can reach port 8443. Verification must run from outside the Tomcat process; a correct config file is not proof.
  • Your Tomcat major version. Attribute names differ between 8.5/9 and 10/11; wrong syntax causes startup failure.
  • Your JDK version. TLSv1.0 and TLSv1.1 are disabled by default in Java 8u292 and later via jdk.tls.disabledAlgorithms in $JAVA_HOME/conf/security/java.security, so a modern JDK may already refuse these protocols even if Tomcat requests them. ChaCha20-Poly1305 suites may require a newer JDK; verify before including them.

Procedure

1. Identify the Tomcat version and connector type

$CATALINA_HOME/bin/version.sh

The version determines which syntax you must use. On Tomcat 10.1 and later, the APR/Native connector (Http11AprProtocol) is reported as removed; use Http11NioProtocol. If you previously relied on APR for TLS performance, switch to NIO with the OpenSSL implementation via sslImplementationName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation" on the SSLHostConfig.

2. Locate the 8443 connector

grep -A 15 'port="8443"' $CATALINA_BASE/conf/server.xml

Note any existing sslEnabledProtocols, ciphers, sslProtocol, keystoreFile, or keystorePass attributes on the <Connector> element. On Tomcat 8.5/9 these are deprecated aliases for attributes on an auto-created SSLHostConfig with hostname _default_. On Tomcat 10/11 they are removed and cause a startup error like “failed to set property [sslEnabledProtocols]”.

3. Configure protocols

The configuration splits by major version.

flowchart td
  A[Identify Tomcat major version] --> B{8.5 or 9.x?}
  B -- yes --> C[sslEnabledProtocols works but deprecated]
  B -- no --> D{10.x or 11.x?}
  D -- yes --> E[sslEnabledProtocols removed]
  C --> F[Use SSLHostConfig protocols attr]
  E --> F
  F --> G[Set protocols to TLSv1.2,TLSv1.3]
  G --> H[Verify with openssl s_client]

For Tomcat 8.5 and 9.x, the deprecated sslEnabledProtocols attribute on the Connector still works, but the supported path is a nested SSLHostConfig. For Tomcat 10.x and 11.x, SSLHostConfig is mandatory.

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true">
  <SSLHostConfig
      protocols="TLSv1.2,TLSv1.3"
      ciphers="HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!kRSA"
      cipherSuites="TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256">
    <Certificate certificateKeystoreFile="conf/keystore.p12"
                 certificateKeystorePassword="changeit"
                 type="RSA" />
  </SSLHostConfig>
</Connector>

Key points:

  • protocols="TLSv1.2,TLSv1.3" restricts the protocol list to an explicit set. If you omit protocols, the default is all, which expands to include TLSv1.0 and TLSv1.1. Omitting the attribute is how most weak-protocol exposures happen. The protocols attribute also accepts +/- prefix modifiers against the default set (for example, all,-TLSv1,-TLSv1.1), but an explicit list is clearer for auditing.
  • sslProtocol is not protocols. Setting sslProtocol="TLSv1.2" does not restrict the allowed list to TLSv1.2. Use protocols on SSLHostConfig to control which versions are negotiated.
  • Remove all deprecated Connector-level SSL attributes (keystoreFile, keystorePass, ciphers, sslProtocol, sslEnabledProtocols) when you add an explicit SSLHostConfig. Mixing them causes Tomcat to auto-create a second SSLHostConfig for _default_, and startup fails with “Multiple SSLHostConfig elements were provided for the host name [default]. Hostnames must be unique.”

4. Configure ciphers

The cipher attribute split in Tomcat 9.0.115, 10.1.52, and 11.0.18 is the most common silent regression. Before those versions, a single ciphers attribute held both TLSv1.2 and TLSv1.3 cipher names. After, ciphers is for TLSv1.2 and below, and cipherSuites is for TLSv1.3.

If you place TLSv1.3 cipher names (anything starting with TLS_AES_ or TLS_CHACHA20_) in the ciphers attribute on a split version, Tomcat logs a warning and ignores them. The connector then offers all default TLSv1.3 ciphers, including any you intended to exclude. The warning looks like: “The TLS 1.3 cipher suite [TLS_AES_256_GCM_SHA384] included in the TLS 1.2 and below ciphers list will be ignored”.

Check your version and use both attributes on split versions. On earlier 9.0.x or 10.1.x, place all cipher names in ciphers.

5. Apply the change

Tomcat does not hot-reload SSL configuration. A restart is required.

# Restart Tomcat (adjust for your init system)
sudo systemctl restart tomcat

Watch the startup log for SSL errors. A failed SSLHostConfig prevents the connector from binding to 8443, so the JVM stays alive but the HTTPS port does not listen. A process-alive check is not sufficient.

Verifying it works

Verification must be external. The config file is not the source of truth for what the connector offers.

# Verify TLSv1.0 is refused (should fail or show no protocol)
openssl s_client -connect localhost:8443 -tls1 </dev/null 2>&1 | grep -i "protocol\|error"

# Verify TLSv1.1 is refused
openssl s_client -connect localhost:8443 -tls1_1 </dev/null 2>&1 | grep -i "protocol\|error"

# Verify TLSv1.2 works
openssl s_client -connect localhost:8443 -tls1_2 </dev/null 2>&1 | grep -i "protocol"

# Verify TLSv1.3 works
openssl s_client -connect localhost:8443 -tls1_3 </dev/null 2>&1 | grep -i "protocol"

# Enumerate all offered ciphers and grades
nmap --script ssl-enum-ciphers -p 8443 localhost

Expected results:

  • -tls1 and -tls1_1 should fail with a handshake or protocol error. If either connects and reports Protocol : TLSv1 or TLSv1.1, the restriction did not take effect. Note: on OpenSSL 3.x, these flags may not be available if TLS 1.0 support was compiled out on the client side. Use an older OpenSSL or a tool like testssl.sh if you need to confirm from a legacy client perspective.
  • -tls1_2 and -tls1_3 should connect successfully.
  • nmap ssl-enum-ciphers should list only strong ciphers with no TLSv1.0 or TLSv1.1 section.

Run these from a host outside the Tomcat server. A localhost check confirms the connector config; an external check confirms firewalls, load balancers, and TLS-terminating proxies are not re-enabling weak protocols.

Common pitfalls

  • sslProtocol is not sslEnabledProtocols. sslProtocol controls the protocol version negotiated, not the allowed list. Setting sslProtocol="TLSv1.2" does not disable TLSv1.0 and TLSv1.1. Use protocols on SSLHostConfig.
  • Cipher downgrade on upgrade. Moving to Tomcat 9.0.115+, 10.1.52+, or 11.0.18+ with TLSv1.3 cipher names still in ciphers silently re-enables all default TLSv1.3 ciphers. Check the log for the “will be ignored” warning after every upgrade.
  • Multiple SSLHostConfig error. Mixing deprecated Connector-level SSL attributes with an explicit SSLHostConfig produces “Multiple SSLHostConfig elements were provided for the host name [default]”. Remove all deprecated attributes from the Connector.
  • ChaCha20 on Java 11. The TLS_CHACHA20_POLY1305_SHA256 suite may require Java 12 or later. On Java 11, omit it from cipherSuites or the connector may fail to start.
  • JDK already disables TLSv1.0/1.1. Java 8u292+ disables TLSv1.0 and TLSv1.1 via jdk.tls.disabledAlgorithms. A scanner may still report them if the JDK config was modified. Verify the JDK config, not just Tomcat.

Signals to monitor

SignalWhy it mattersWarning sign
8443 port listeningConnector failed to start after config changess -tnl sport = :8443 shows no listener
TLS handshake success rateMisconfigured ciphers cause handshake failuresSpike in connection resets or client-side TLS errors
Certificate expirySilent total outage independent of protocol/cipher configDays to expiry approaching zero; needs external check
Startup log for SSL warningsCipher downgrade bug is silent except for a log line“will be ignored” warning after upgrade

How Netdata helps

  • Port and service checks. TCP and HTTP checks confirm 8443 is listening and completing a TLS handshake after a config change, catching the case where the JVM is alive but the connector failed to start.
  • Process-alive correlation. Pairing the port check with the JVM process-alive signal distinguishes “Tomcat is down” from “Tomcat is up but the HTTPS connector did not bind”.
  • External certificate expiry monitoring. Certificate checks probe the chain from outside the host, which is the only reliable way to catch expiry before it becomes a total outage.
  • Error rate correlation. A spike in 5xx errors or connection resets immediately after a TLS config change points back to the cipher or protocol restriction.
  • Startup log monitoring. The “will be ignored” cipher warning in catalina.out is the only in-process signal for the silent cipher downgrade bug.