elastic/elasticsearch · error · RuntimeException
thread waiting for the response was interrupted
Error message
thread waiting for the response was interrupted
What it means
Thrown by extractAndWrapCause when the future completing a sync performRequest was cancelled/interrupted. The client re-asserts the interrupt flag (Thread.currentThread().interrupt()) and wraps the original InterruptedException in a RuntimeException so it can surface through methods that only declare checked exceptions. This is a programmer/environment signal, not a server error.
Source
Thrown at client/rest/src/main/java/org/elasticsearch/client/RestClient.java:904
ResponseOrResponseException(Response response) {
this.response = Objects.requireNonNull(response);
this.responseException = null;
}
ResponseOrResponseException(ResponseException responseException) {
this.responseException = Objects.requireNonNull(responseException);
this.response = null;
}
}
/**
* Wrap the exception so the caller's signature shows up in the stack trace, taking care to copy the original type and message
* where possible so async and sync code don't have to check different exceptions.
*/
private static Exception extractAndWrapCause(Exception exception) {
if (exception instanceof InterruptedException) {
Thread.currentThread().interrupt();
throw new RuntimeException("thread waiting for the response was interrupted", exception);
}
if (exception instanceof ExecutionException) {
ExecutionException executionException = (ExecutionException) exception;
Throwable t = executionException.getCause() == null ? executionException : executionException.getCause();
if (t instanceof Error) {
throw (Error) t;
}
exception = (Exception) t;
}
if (exception instanceof ConnectTimeoutException) {
ConnectTimeoutException e = new ConnectTimeoutException(exception.getMessage());
e.initCause(exception);
return e;
}
if (exception instanceof SocketTimeoutException) {
SocketTimeoutException e = new SocketTimeoutException(exception.getMessage());
e.initCause(exception);
return e;View on GitHub (pinned to db6a809a66)
Solutions
- Ensure no other thread interrupts or shuts down the client/executor while a request is in flight.
- If you intentionally cancel, treat this RuntimeException as expected and re-check Thread.interrupted() in your handler.
- Avoid sharing one RestClient across threads that may close it independently.
Example fix
// before new Thread(() -> client.performRequest(req)).start(); // later, from another thread: client.close(); // interrupts the in-flight request // after // drain/await outstanding requests, then close: client.close(); // only after no caller is mid-request
Defensive patterns
Strategy: try-catch
Try / catch
try { client.performRequest(req); }
catch (RuntimeException e) {
if (e.getCause() instanceof InterruptedException) {
Thread.currentThread().interrupt();
// handle shutdown/cancellation gracefully
} else throw e;
} Prevention
- Do not close the RestClient from a different thread while requests are pending.
- Own request lifecycle: await completion before teardown.
- If you must interrupt, propagate the interrupt and treat this exception as expected.
When it happens
Trigger: The thread blocked in performRequest is interrupted (Thread.interrupt) while waiting on the async future; the RestClient is shut down while a request is in flight; the surrounding executor cancels the task.
Common situations: Calling RestClient.close() from another thread while a request is pending; shutting down an ExecutorService that wraps the client call; test timeouts interrupting the request thread.
Related errors
- Interrupted while waiting for {}
- Retry interrupted
- Cannot add nodes to test cluster after is has been frozen
- Configuration for {} can not be altered, already locked
- Can not start {}, missing: {}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/63445a39e0ec564d.
Report an issue: GitHub.