Java HttpClient timeout: no default, so set two of them
Java's HttpClient has no request timeout unless you set one: connectTimeout on the client, timeout on each request, and HttpTimeoutException.

The Java HttpClient (java.net.http, since Java 11) has no request timeout by default: the javadoc says not setting one is the same as an infinite duration, so send blocks forever if no response comes. Set two timeouts: HttpClient.Builder.connectTimeout(Duration) for opening a connection, and HttpRequest.Builder.timeout(Duration) for each request's response. When one expires, send throws HttpTimeoutException, or HttpConnectTimeoutException for the connect phase.
Java facts come from the Java SE 21 javadoc for HttpClient, HttpClient.Builder, HttpRequest.Builder and HttpTimeoutException. The slow-API example is Sume's, from Jobs and results and Video Generation, all read on 2026-09-29.
What are the Java HttpClient timeout settings?
There are two, set in two places, and HttpClient.newHttpClient() sets neither.
| Setting | Covers | If not set | On expiry |
|---|---|---|---|
HttpClient.Builder.connectTimeout(Duration) | Establishing a new connection; no effect when a connection is reused | connectTimeout() returns an empty Optional | HttpConnectTimeoutException |
HttpRequest.Builder.timeout(Duration) | Receiving the response to this request | Same as an infinite duration: block forever | HttpTimeoutException |
How do I set a timeout on a Java HttpClient request?
Put connectTimeout on the client you reuse and timeout on each request. A non-positive duration makes timeout throw IllegalArgumentException. HttpConnectTimeoutException extends HttpTimeoutException, which extends IOException, so catch the narrower one first. With sendAsync, the future completes exceptionally with the same exceptions instead.
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10)) // new connections only
.build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sume.com/v1/videos"))
.timeout(Duration.ofSeconds(30)) // this request's response
.header("Authorization", "Bearer " + System.getenv("SUME_API_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", "order-8823-clip-v1")
.POST(HttpRequest.BodyPublishers.ofString(
"{\"model\":\"sume/auto\",\"prompt\":\"A product clip on a desk\",\"aspect_ratio\":\"9:16\",\"duration\":5}"))
.build();
try {
HttpResponse<String> res = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(res.statusCode() + " " + res.body()); // 202: id, polling_url
} catch (HttpConnectTimeoutException e) {
// no connection within 10 s: retry with the same Idempotency-Key
} catch (HttpTimeoutException e) {
// no response within 30 s: the job may exist; retry with the same key
}How long should the timeout be for a slow API?
Short, because an async job API answers before the work is done. Sume's video create returns a job id and polling URL immediately, and you poll GET /v1/videos/{jobId} until the status is completed. Where a Sume submit endpoint offers the blocking sync mode, it waits at most 30 seconds and then returns the job, so no create call needs a request timeout measured in minutes. Put the long deadline in your polling loop instead: Sume's jobs guide calls 20 minutes reasonable for video, and says that deadline is client-side.
Give each status poll the same short per-request timeout, and treat an HttpTimeoutException on a poll as one missed read, not a failed job: wait with exponential backoff and poll again, and stop only when the status is terminal. The connect timeout matters less here, because it has no effect when the client reuses an open connection.
What happens to the job when HttpClient times out?
It keeps running. A client-side timeout does not cancel the job; it keeps running and still bills. Keep the job id and pick it back up from the status URL, and don't resubmit the paid request because a local process timed out. If the create timed out before you saw an id, resend it with the same Idempotency-Key, and the retry returns the original job instead of billing a second one. Spring Retry for paid API calls wraps that retry, and text to speech API in Java shows a full submit-and-poll loop.
Sources
- Java SE 21: HttpClient (read 2026-09-29)
- Java SE 21: HttpClient.Builder (read 2026-09-29)
- Java SE 21: HttpRequest.Builder (read 2026-09-29)
- Java SE 21: HttpTimeoutException (read 2026-09-29)
- Java SE 21: HttpConnectTimeoutException (read 2026-09-29)
- Java SE 21: HttpRequest.BodyPublishers (read 2026-09-29)
- Jobs and results
- Video Generation
Related posts
More in Developers
- 409 job_not_completed: why the result call fails and what to poll
GET /v1/jobs/:id/result answers 409 job_not_completed until the job completes. Poll status for terminal, read failures from the job record, and never resubmit.
- JSON to video API: render an MP4 from a timeline document
A JSON to video API renders one MP4 from a document that says which clips play when, over which audio. How Sume's Timeline 1.0 does it, and costs.
- Kling API rate limit: concurrency by package and error 1303
Kling's API limits concurrent tasks by resource package, not requests per second. Over the cap, a create fails with HTTP 429, code 1303.
- MCP 2026-07-28 spec: which version does Sume's hosted server speak?
The 2026-07-28 MCP revision is out and Claude Code speaks it. Sume's hosted server negotiates 2025-03-26, 2025-06-18 and 2025-11-25, not 2026-07-28.
Written by Sume