prestodb/presto · error · RuntimeException
ResultSet thread was interrupted
Error message
ResultSet thread was interrupted
What it means
Wrapped SQLException raised inside the ResultSet's async iteration driver thread when Thread.currentThread().isInterrupted() is true. The client connection is closed first, then a RuntimeException carrying the SQLException (with the original cause t) is thrown. It indicates the thread fetching results was interrupted, typically at shutdown or by executor cancellation.
Source
Thrown at presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoResultSet.java:1831
}
}
verify(client.isFinished());
QueryStatusInfo results = client.finalStatusInfo();
progressCallback.accept(QueryStats.create(results.getId(), results.getStats()));
warningsManager.addWarnings(results.getWarnings());
if (results.getError() != null) {
throw new RuntimeException(resultsException(results));
}
return endOfData();
}
private void checkInterruption(Throwable t)
{
if (Thread.currentThread().isInterrupted()) {
client.close();
throw new RuntimeException(new SQLException("ResultSet thread was interrupted", t));
}
}
}
static SQLException resultsException(QueryStatusInfo results)
{
QueryError error = requireNonNull(results.getError());
String message = format("Query failed (#%s): %s", results.getId(), error.getMessage());
Throwable cause = (error.getFailureInfo() == null) ? null : error.getFailureInfo().toException();
return new SQLException(message, error.getSqlState(), error.getErrorCode(), cause);
}
private static Map<String, Integer> getFieldMap(List<Column> columns)
{
Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < columns.size(); i++) {
String name = columns.get(i).getName().toLowerCase(ENGLISH);
if (!map.containsKey(name)) {View on GitHub (pinned to 55bb57d202)
Solutions
- Close ResultSet/Statement/Connection before interrupting or shutting down the executor
- Use query cancellation (Statement.cancel()) instead of Thread.interrupt() to stop a running query
- Avoid interrupting threads that own JDBC fetches; run queries with proper lifecycle management
- Restore the interrupt status or handle shutdown gracefully in the calling code
- Inspect the cause (t) to find who issued the interrupt
Example fix
// before executor.shutdownNow(); // interrupts in-flight JDBC fetch // after stmt.cancel(); // cancel the Presto query first rs.close(); stmt.close(); executor.shutdown();
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the owning executor is not shut down before iterating
if (executor.isShutdown()) throw new IllegalStateException("Executor shut down; do not start ResultSet iteration"); Try / catch
try (ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) { /* ... */ }
} catch (RuntimeException | SQLException e) {
Throwable cause = e.getCause();
if (cause instanceof SQLException && cause.getMessage() != null && cause.getMessage().contains("ResultSet thread was interrupted")) {
Thread.currentThread().interrupt(); // preserve interrupt status
return; // graceful shutdown path
}
throw e;
} Prevention
- Close JDBC resources before interrupting worker threads or shutdownNow()
- Use Statement.cancel() rather than Thread.interrupt() to stop Presto queries
- Order shutdown: close results/statements first, then executors
- Preserve and inspect the interrupt cause to find the interrupting component
When it happens
Trigger: The thread executing ResultSet iteration (checkInterruption path) is interrupted via Thread.interrupt(), e.g. during application shutdown, executor shutdownNow, query cancellation, or a timeout that interrupts the worker.
Common situations: Cancelling long-running queries via Future.cancel(true); ExecutorService.shutdownNow() while JDBC fetch threads are blocked; Tomcat/request timeouts interrupting worker threads; poor shutdown ordering where the pool closes before statements do.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/a5524d520966330b.
Report an issue: GitHub.