Hi Arpan, We have filed a ticket to address your "ClientHello with no supported_groups or key_share extension" observation: https://bugs.openjdk.org/browse/JDK-8392803
Thank you, Artur ________________________________ From: Arpan Sharma <[email protected]> Sent: Monday, July 27, 2026 14:09 To: Sean Mullan <[email protected]> Cc: [email protected] <[email protected]> Subject: Re: [External] : setNamedGroups() silently drops unsupported named groups — spec/detection gap, still present in JDK 27-ea Hi Sean, That does make sense, thank you. The distinction between what a provider sends by default and what it can negotiate is the one that matters, and I had been conflating the two. The narrower point I was reaching for was about the specification Hi Sean, That does make sense, thank you. The distinction between what a provider sends by default and what it can negotiate is the one that matters, and I had been conflating the two. The narrower point I was reaching for was about the specification rather than provider-independence. The getSupportedSSLParameters javadoc says only that "The parameters will always have the ciphersuites and protocols arrays set to non-null values", so an application reading namedGroups from it is relying on unspecified behaviour even against a provider that does populate it. A first-class method carries its own contract, and that is the part of JDK-8388519 I expect to be most useful in practice. It also supplies the pre-flight check my original case needed. On 27-ea MLKEM768 is recognised but inactive ("Ignore inactive or disabled named group"), and JEP 527 lists non-hybrid ML-KEM key exchange for TLS as a non-goal, so at present an application cannot tell in advance whether a requested group will be used or quietly dropped. Being able to ask before calling setNamedGroups is what closes that. On the ClientHello with no supported_groups or key_share extension, thank you for taking a look. That is case C4 in the matrix at https://github.com/Arpan0995/jdk-tls-namedgroup-silent-drop, which records the debug trace ("Ignore key_share extension, no supported groups") and both peer outcomes: handshake_failure from a Bouncy Castle 1.84 server, and missing_extension from a stock JSSE server. Happy to test any change against it. Thanks again for the time on this. Best regards, Arpan Sharma On Fri, Jul 24, 2026 at 2:33 PM Sean Mullan <[email protected]> wrote: > > > On 7/23/26 6:51 PM, Arpan Sharma wrote: > > > > You probably already know this, but you can set only PQC or hybrid > > named groups if you don't want classical groups to be used. > > I tested that guard too, and it has a sharp edge worth noting: with > setNamedGroups({"MLKEM768"}) alone on a JDK that does not support it, > the call succeeds and nothing fails locally. The client still sends a > ClientHello — with no supported_groups or key_share extension at all > — and the failure surfaces only as the peer's fatal alert, whose type > depends on the peer (a Bouncy Castle 1.84 server produced > handshake_failure; in an earlier test a stock JSSE server produced > missing_extension). So the connection does fail closed, but remotely > and in a way that is hard to attribute to the dropped group. The > supported-groups query API in JDK-8388519 gives applications the > right tool here: check first, then set. > > That does seem a bit odd. We'll take a closer look at that case and see if it > needs to be addressed better. > > On that API, one data point that may be useful for the RFE: on > 26.0.1 and 27-ea, SSLContext.getSupportedSSLParameters() > .getNamedGroups() already returns the provider's supported list (my > reproducer uses it as its baseline). But as far as I can tell the > getSupportedSSLParameters() spec only guarantees that the ciphersuite > and protocol arrays are populated, so an application cannot rely on > it across providers — a first-class API in the style of > getSupportedCipherSuites would give that query an actual contract. > > getSupportedCipherSuites() is also provider specific. It returns all the > suites that a provider implements and can be negotiated. > > SSLContext.getSupportedSSLParameters().getNamedGroups() only returns the > groups that the provider would send to the server by default, > for example in the supported_groups extension. There can be other groups that > the provider may implement but not send by default, > and this new method would return that. Hope that makes sense. > > --Sean
