[External] : Re: Http3 Client times out for an untrusted certificate

Daniel Fuchs daniel.fuchs at oracle.com
Fri Nov 7 09:46:10 UTC 2025


Hi Josiah,

On 07/11/2025 00:55, Josiah Noel wrote:
> It seems that this issue only manifests itself when an httpserver is 
> running tcp on the same port. Attached is a jbang script that 
> illustrates this issue.

Oh - but I had tried that too - and I got the `certificate_unknown`
from the tcp server that time:

Caused by: javax.net.ssl.SSLHandshakeException: (certificate_unknown) 
PKIX path building failed: 
sun.security.provider.certpath.SunCertPathBuilderException: unable to 
find valid certification path to requested target
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:130)
	at 
java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:376)
	at 
java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:319)
	at 
java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:314)
	at 
java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1310)
	at 
java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1172)
	at 
java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1115)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:421)
	at 
java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:477)
	at 
java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:1207)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
	at 
java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.lambda$executeTasks$0(SSLFlowDelegate.java:1148)
	at 
java.net.http/jdk.internal.net.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:188)
	at 
java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.executeTasks(SSLFlowDelegate.java:1143)
	at 
java.net.http/jdk.internal.net.http.common.SSLFlowDelegate.doHandshake(SSLFlowDelegate.java:1109)
	at 
java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader.processData(SSLFlowDelegate.java:508)
	at 
java.net.http/jdk.internal.net.http.common.SSLFlowDelegate$Reader$ReaderDownstreamPusher.run(SSLFlowDelegate.java:283)
	at 
java.net.http/jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask.run(SequentialScheduler.java:182)
	at 
java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:149)
	at 
java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:207)
	at 
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090)
	at 
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614)
	... 1 more

Does the server supports https? Because if the server does not
support https it might just be trying to read the request line
before responding, and the client might be waiting for the server
hello. The same would happen with HTTP/1.1 if you tried to use
https with a server that only supports http.

I will try your script and investigate further.

When only specifying HTTP/3 the client will try both Quic and TCP
and fallback to TCP if Quic fails.

It's possible to change that behaviour by specifying an H3_DISCOVERY
option at the request level.

Jaikiran wrote a very good article which explains that:
https://inside.java/2025/10/22/http3-support/

cheers,

-- daniel



More information about the net-dev mailing list