From 9587fb73dd90f8b9012035a826990b091995ab45 Mon Sep 17 00:00:00 2001 From: Gaurav Narula Date: Wed, 22 Oct 2025 13:35:25 +0100 Subject: [PATCH] MINOR: improve error message on cert validation failure A TLS handshake failure results in an `INFO` log with a generic message of `SSL handshake failed`. The absence of a stacktrace, which I believe is to avoid polluting the logs in case of a misbehaving client, makes it hard to diagnose the underlying cause of the handshake failure. This change modifies the message to include the certificate failure reason which can provide a valuable hint to users regarding the underlying issue during an incident. --- .../org/apache/kafka/common/network/Selector.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/clients/src/main/java/org/apache/kafka/common/network/Selector.java b/clients/src/main/java/org/apache/kafka/common/network/Selector.java index 7acf88269ee14..0bac3161155bf 100644 --- a/clients/src/main/java/org/apache/kafka/common/network/Selector.java +++ b/clients/src/main/java/org/apache/kafka/common/network/Selector.java @@ -42,6 +42,7 @@ import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; import java.nio.channels.UnresolvedAddressException; +import java.security.cert.CertPathValidatorException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -619,6 +620,10 @@ void pollSelectionKeys(Set selectionKeys, String exceptionMessage = e.getMessage(); if (e instanceof DelayedResponseAuthenticationException) exceptionMessage = e.getCause().getMessage(); + CertPathValidatorException certPathValidatorException = maybeGetCertPathValidatorException(e); + if (certPathValidatorException != null) { + exceptionMessage += "; certificate validation failed with reason " + certPathValidatorException.getReason(); + } log.info("Failed {}authentication with {} ({})", isReauthentication ? "re-" : "", desc, exceptionMessage); } else { @@ -635,6 +640,14 @@ void pollSelectionKeys(Set selectionKeys, } } + private CertPathValidatorException maybeGetCertPathValidatorException(Throwable throwable) { + Throwable current = throwable; + while (current != null && !(current instanceof CertPathValidatorException)) { + current = current.getCause(); + } + return (CertPathValidatorException) current; + } + private void attemptWrite(SelectionKey key, KafkaChannel channel, long nowNanos) throws IOException { if (channel.hasSend() && channel.ready()