Fehlermeldung
No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
Auch ausgegeben als
- javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
Der Wortlaut ist von den Updates für JDK 8 bis JDK 25 derselbe. Auf der Serverseite einer JVM erscheint dieselbe Situation als „No appropriate protocol“, wenn alle ihre eigenen Protokolle deaktiviert sind.
Java (JSSE) — the client itself has no enabled protocol/cipher combination left
Was der Fehler bedeutet
Die JVM konnte nicht einmal ein ClientHello bauen: Nachdem alle in jdk.tls.disabledAlgorithms aufgeführten Protokolle und Cipher Suites entfernt waren, blieb nichts mehr übrig, was die Anwendung angefordert hatte. Typischerweise besteht der Code oder die Konfiguration auf TLS 1.0, TLS 1.1 oder SSLv3, die in aktuellen JDKs alle deaktiviert sind. An den Server wurde nichts gesendet.
Warum der Fehler auftritt
Die Anwendung erzwingt ein altes Protokoll
häufigSSLContext.getInstance("TLSv1"), setEnabledProtocols(new String[]{"TLSv1"}) oder https.protocols=TLSv1, vor Jahren für einen Legacy-Server eingetragen.
Ein JDK-Update hat deaktiviert, was die Anwendung verwendet hat
häufigTLS 1.0 und 1.1 wurden mit den Sicherheitsupdates von 2021 für Java 8, 11 und neuer standardmäßig deaktiviert; Anwendungen, die nur damit liefen, funktionieren nach dem Upgrade nicht mehr.
Eine explizite Liste von Cipher Suites enthält nur deaktivierte Suites
gelegentlichKonfigurationen, die nur ein paar TLS_RSA_*- oder 3DES-Suites aufführen, lassen nichts Brauchbares übrig, sobald diese deaktiviert sind.
So behebst du den Fehler
- 1.
Finden, wo das alte Protokoll angefordert wird
Durchsuche Code und JVM-Optionen nach explizit genannten Protokollnamen; -XshowSettings:security:tls zeigt, was das JDK aktiviert hat.
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.
„TLS“ anfordern und JSSE aushandeln lassen
SSLContext.getInstance("TLS") aktiviert auf aktuellen JDKs TLS 1.3 und 1.2.
java // Let JSSE negotiate the best version (TLS 1.3 / 1.2) SSLContext ctx = SSLContext.getInstance("TLS"); ctx.init(null, null, null); - 3.
Letzter Ausweg: eine eng begrenzte Ausnahme für einen einzelnen Legacy-Endpunkt
Lässt sich ein Gerät nicht aktualisieren, kann eine separate Security-Properties-Datei TLSv1/TLSv1.1 aus jdk.tls.disabledAlgorithms für die JVM entfernen, die mit diesem Gerät kommuniziert. Geh vom vollständigen aktuellen Wert des JDK aus, ändere nur die Protokolleinträge und isoliere diese 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