Mensagem de erro
No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
Também aparece como
- javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
O texto é o mesmo das atualizações do JDK 8 até o JDK 25. Quando a JVM atua como servidor, a mesma condição aparece como “No appropriate protocol” se todos os protocolos dela estiverem desativados.
Java (JSSE) — the client itself has no enabled protocol/cipher combination left
O que significa
A JVM não conseguiu nem montar um ClientHello: depois de remover todos os protocolos e cipher suites listados em jdk.tls.disabledAlgorithms, não sobra nada do que a aplicação pediu. Normalmente, o código ou a configuração insiste em TLS 1.0, TLS 1.1 ou SSLv3, todos desativados nos JDKs atuais. Nada foi enviado ao servidor.
Por que acontece
A aplicação força um protocolo antigo
comumSSLContext.getInstance("TLSv1"), setEnabledProtocols(new String[]{"TLSv1"}) ou https.protocols=TLSv1, escritos anos atrás para um servidor legado.
Uma atualização do JDK desativou o que a aplicação usava
comumO TLS 1.0 e o 1.1 foram desativados por padrão nas atualizações de segurança de 2021 do Java 8, do 11 e das versões posteriores; aplicações que só funcionavam com eles quebram depois da atualização.
Todas as cipher suites de uma lista explícita estão desativadas
ocasionalConfigurações que listam algumas cipher suites TLS_RSA_* ou 3DES ficam sem nada utilizável quando elas são desativadas.
Como corrigir
- 1.
Encontrar onde o protocolo antigo é solicitado
Procure nomes de protocolo explícitos no código e nas opções da JVM; a opção -XshowSettings:security:tls mostra o que o JDK tem ativado.
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.
Solicitar “TLS” e deixar o JSSE negociar
SSLContext.getInstance("TLS") ativa o TLS 1.3 e o 1.2 nos JDKs atuais.
java // Let JSSE negotiate the best version (TLS 1.3 / 1.2) SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(null, null, null); - 3.
Último recurso: uma sobrescrita restrita a um único endpoint legado
Se um dispositivo não puder ser atualizado, um arquivo de propriedades de segurança separado pode remover TLSv1/TLSv1.1 de jdk.tls.disabledAlgorithms para a JVM que se comunica com ele. Parta do valor atual completo do JDK, altere apenas as entradas de protocolo e isole essa 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