Hi Mickael, Thank you for the KIP.
I wonder if we should also introduce a metric to identify the named group a TLS connection is using. That would be of use to operators who’d like to track PQC adoption across clients connecting to their Kafka cluster. I think the selector metrics track TLS protocol and cipher information so there’s some precedent for it. As far as JDK support goes, I think we’d be able to get this information from JDK 28 onwards [0] (or earlier if a vendor backports it). [0]: https://bugs.openjdk.org/browse/JDK-8388519 Regards, Gaurav Narula > On 16 Oct 2026, at 19:47, Arnab nandy via dev <[email protected]> wrote: > > Hi Aditya, > > I'm sharing my POV based on implementation PR #22865. > > For AK2, DefaultSslEngineFactory resolves SSLParameters.setNamedGroups() once > during class initialization and stores it in a static final Method. The > method is invoked only when ssl.named.groups is non-empty. Using reflection > avoids a compile-time dependency on the Java 20 API while Kafka clients > continue to support earlier Java versions. > > For AK3, the Java-version check and InvalidConfigurationException are > behavior of the default SSL engine factory. A custom ssl.engine.factory.class > may support named groups through another mechanism, so I don’t think Kafka > should require every custom implementation to follow the reflection-based > behavior. It would be useful for the KIP to make the scope of that guarantee > explicit. > > For AK5, invalid group names supplied to setNamedGroups() are already wrapped > in an InvalidConfigurationException. If both endpoints support the configured > groups individually but have no group in common, that is discovered during > the handshake and remains an SSLHandshakeException from JSSE. Listing only > the local JVM’s supported groups may be misleading because Kafka does not > know the peer’s supported groups at that point. > > For AK6, the negative test has now been added to PR #22865. On Java versions > below 20, it verifies that a non-empty ssl.named.groups causes an > InvalidConfigurationException. The Java 17 CI lane will exercise that path. > > Regarding AK7, I agree that a multi-release JAR is technically possible, but > it introduces additional build and shading complexity for a single API call. > Reflection appears to be the simpler and more robust option here. > > Thanks, > Arnab > > On 2026-10-16 15:30 UTC Aditya Kousik via dev wrote: >> Hi Mickael, >> >> Thanks for the KIP. It’s good to see Kafka take on the PQC world; I had a >> few comments. >> >> AK1: nit: but the Status is still marked as Draft and the Discussion Link is >> still TBD >> >> AK2: The reflection mechanism could use some details. Are we storing a >> MethodHandle reference when DefaultSslEngineFactory initializes in a static >> block? >> >> AK3: If the contract is to throw ConfigException because of missing names >> group support on the jdk, there’s nothing in the SslEngineFactory to have >> other engines follow the spec. ssl.engine.factory.class for other engines >> won’t adhere to this, and may break silently after launch. >> >> AK4: Should we file a JIRA in conjunction to deprecate/cleanup the >> reflection once all clients and servers update their minimum supported >> version >= 20? >> >> AK5: >>> a TLS connection can only be established when the client and server share >>> at least one named group >> >> I see in other replies than this would this be an sslhandshakexception that >> the jdk SSLEngine throws. Would it be worth adding a custom KafkaException >> that suggests to users on the supported named groups in the current VM via >> SSLContext.getSupportedSSLParameters().getNamedGroups(). We sometimes do >> this when serialization fails, max poll interval elapses etc. >> >> AK6: On Testing, there’s a negative test that we’re missing. We can ensure >> assertThrows(ConfigException.class) on jdk versions < 20 which maybe a lot >> of the clients out there. >> >> AK7: I think for the simplicity alone, reflection is what we might settle >> on. But I wanted to call out that there’s technically another approach that >> might get us there without it. >> We could do a multi-release JAR which has been available since jdk9. We can >> create a custom java20 source set and have gradle include it in the build. >> We can define a plain class on the base layer as >> ```java >> public class NamedGroupSupport { >> public boolean supported() { return false; } >> public void apply(SSLParameters sslParams, String[] groups) { throw new >> UnsupportedOperationException(); } >> } >> ``` >> And in the java20 source set, have the right implementation. We also need >> ```groovy >> jar { >> into(‘META-INF/versions/20’) { from sourceSets.java20.output } >> manifest { attributes ‘Multi-Release’: ‘true’ } >> } >> ``` >> With the above in addition to a custom java20 source set with >> options.release = 20 could get us there for free. >> >> But the cost is the build complexity, if someone shades the kafka-clients >> JAR they lose support. Also for clients who fork and build their own JARs >> this would not be preferable. So overall, reflection is the simpler answer I >> think but an alternative nonetheless to reject imo. >> >> Thanks, >> Aditya Kousik >> >> On 2026-10-06 10:14 UTC Mickael Maison wrote: >>> Hi, >>> >>> I'd like to start a discussion about KIP-1376 which proposes adding >>> support for TLS named groups: >>> https://cwiki.apache.org/confluence/x/dJXwGg >>> >>> Thanks, >>> Mickael >>> >>
