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

  1. Close ResultSet/Statement/Connection before interrupting or shutting down the executor
  2. Use query cancellation (Statement.cancel()) instead of Thread.interrupt() to stop a running query
  3. Avoid interrupting threads that own JDBC fetches; run queries with proper lifecycle management
  4. Restore the interrupt status or handle shutdown gracefully in the calling code
  5. 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

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.