Http 3 Client request timeout not respected

Jaikiran Pai jaikiran.pai at oracle.com
Tue Nov 11 05:22:40 UTC 2025


Hello Josiah,

In my previous mail, I mentioned an incorrect system property to 
configure for the timeout. The right one is 
"jdk.httpclient.quic.idleTimeout". This one too takes a value in 
seconds. So configuring it to "-Djdk.httpclient.quic.idleTimeout=50" 
(for example) would be useful in the application code you are 
experimenting with. Let us know how it works out.

-Jaikiran

On 10/11/25 7:31 pm, Jaikiran Pai wrote:
>
> Looking at the application code, the relevant parts appear to be this:
>
> ServerConnectionConfig.builder()
>         .maxIdleTimeoutInSeconds(50)
> ...
> new Http3ApplicationProtocolFactory(
>     (request, response) -> {
>       try {
>         Thread.sleep(Duration.ofSeconds(40));
>       } catch (InterruptedException e) {
>         Thread.interrupted();
>       }
>       response.setStatus(200);
> ...
> HttpClient.newBuilder()
>   .version(Version.valueOf("HTTP_3"))
>   .sslContext(sslContext)
>   .build()
>   .send(
>       HttpRequest.newBuilder()
>           .timeout(Duration.ofSeconds(45))
>           .uri(URI.create("https://localhost:8080"))
>           .GET()
>
> The server is configured to have a QUIC idle timeout of 50 seconds. On 
> the client side, the JDK's HttpClient for HTTP/3 by default uses a 
> idle timeout of 30 seconds. These timeouts translate to the QUIC 
> connection level idle timeouts, which decide when to terminate the 
> connection if there's no UDP traffic on that connection. The QUIC RFC 
> specifies that each of the endpoints (the server and the client) can 
> choose to advertise a idle timeout of their own, but the negotiated 
> idle timeout will always be the lower of those two and that negotiated 
> timeout must be honoured by both sides of the connection. So in this 
> case, the server advertises 50 seconds and the client advertises 30 
> seconds, so the 30 second timeout is the negotiated one for this 
> connection and thus if the connection doesn't generate any traffic for 
> that duration (like in this case), it gets idle terminated.
>
> The default idle timeout for JDK's HttpClient can be configured using 
> the "jdk.httpclient.keepalive.timeout.h3" system property 
> https://download.java.net/java/early_access/jdk26/docs/api/java.net.http/module-summary.html. 
> So setting it to -Djdk.httpclient.keepalive.timeout.h3=50 (for 
> example), should then allow your application to stay idle without 
> generating any UDP traffic for the QUIC connection for that long.
>
> -Jaikiran
>
> On 10/11/25 7:08 pm, Josiah Noel wrote:
>> To emulate a few of my worst case latency scenarios that I have seen 
>> in production, I have added a sleep with a thirty second timer before 
>> I send a 200 status.
>>
>> Once more I have attached my jbang script as well as the extended 
>> logs when I ran with 
>> -Djdk.httpclient.HttpClient.log=requests,headers,errors,http3,quic:control:retransmit.
>> -- 
>> Cheers, Josiah.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/net-dev/attachments/20251111/cb89d5d9/attachment.htm>


More information about the net-dev mailing list