Error message
No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
Also printed as
- javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
The wording is the same from JDK 8 updates to JDK 25. On the server side of a JVM the same condition appears as "No appropriate protocol" when its own protocols are all disabled.
Java (JSSE) — the client itself has no enabled protocol/cipher combination left
What it means
The JVM could not even build a ClientHello: after removing every protocol and cipher suite listed in jdk.tls.disabledAlgorithms, nothing the application asked for remains. Typically the code or configuration insists on TLS 1.0, TLS 1.1 or SSLv3, all disabled in current JDKs. Nothing was sent to the server.
Why it happens
The application forces an old protocol
commonSSLContext.getInstance("TLSv1"), setEnabledProtocols(new String[]{"TLSv1"}), or https.protocols=TLSv1 written years ago for a legacy server.
A JDK update disabled what the application used
commonTLS 1.0 and 1.1 were disabled by default in 2021 security updates of Java 8, 11 and later; applications that only worked with them break after upgrading.
An explicit cipher suite list contains only disabled suites
occasionalConfigurations listing a few TLS_RSA_* or 3DES suites leave nothing usable once those are disabled.
How to fix it
- 1.
Find where the old protocol is requested
Search the code and JVM options for explicit protocol names; -XshowSettings:security:tls shows what the JDK has enabled.
bash grep -rnE 'SSLContext.getInstance\("(TLSv1|TLSv1\.1|SSL)"\)|setEnabledProtocols|https\.protocols' src/ java -XshowSettings:security:tls -version 2>&1 | sed -n '/Enabled Protocols/,/Enabled Cipher/p' - 2.
Request "TLS" and let JSSE negotiate
SSLContext.getInstance("TLS") enables TLS 1.3 and 1.2 on current JDKs.
java // Let JSSE negotiate the best version (TLS 1.3 / 1.2) SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(null, null, null); - 3.
Last resort: a narrow override for one legacy endpoint
If a device cannot be upgraded, a separate security properties file can drop TLSv1/TLSv1.1 from jdk.tls.disabledAlgorithms for the JVM that talks to it. Start from the JDK's full current value, change only the protocol entries, and isolate that JVM.
bash # Last resort for ONE legacy endpoint: take this JDK's own value and drop only TLSv1/TLSv1.1 v=$(sed -n '/^jdk.tls.disabledAlgorithms=/,/[^\\]$/p' "$JAVA_HOME/conf/security/java.security" | sed 's/\\$//' | tr -d '\n') printf '%s\n' "$v" | sed -E 's/ TLSv1(\.1)?,//g' > legacy-tls.security java -Djava.security.properties=legacy-tls.security -jar legacy-client.jar