prestodb/presto · error · SQLException

Connection is closed

Error message

Connection is closed

What it means

PrestoConnection.checkOpen() throws this SQLException whenever any connection-level operation (createStatement, prepareStatement, setCatalog, commit, etc.) is invoked after the connection has been closed via close() or aborted. It is a standard JDBC precondition check: the driver has no open HTTP session to the Presto coordinator to send requests on. Once closed, the connection object is permanently unusable; JDBC does not support reopening it.

Source

Thrown at presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoConnection.java:879

    PrestoResultSet invokeQueryInterceptorsPost(String sql, Statement interceptedStatement, PrestoResultSet originalResultSet)
    {
        PrestoResultSet interceptedResultSet = originalResultSet;

        for (QueryInterceptor interceptor : this.queryInterceptorInstances) {
            Optional<PrestoResultSet> newResultSet = interceptor.postProcess(sql, interceptedStatement, interceptedResultSet);
            if (newResultSet.isPresent()) {
                interceptedResultSet = newResultSet.get();
            }
        }
        return interceptedResultSet;
    }

    private void checkOpen()
            throws SQLException
    {
        if (isClosed()) {
            throw new SQLException("Connection is closed");
        }
    }

    private void initializeQueryInterceptors()
    {
        for (QueryInterceptor interceptor : this.queryInterceptorInstances) {
            interceptor.init(this.sessionProperties);
        }
    }

    private static void checkResultSet(int resultSetType, int resultSetConcurrency)
            throws SQLFeatureNotSupportedException
    {
        if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) {
            throw new SQLFeatureNotSupportedException("Result set type must be TYPE_FORWARD_ONLY");
        }
        if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY) {
            throw new SQLFeatureNotSupportedException("Result set concurrency must be CONCUR_READ_ONLY");

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Obtain a fresh connection via DriverManager.getConnection(...) before the operation
  2. Use try-with-resources so a connection is never used after close
  3. If pooling, use a real pool (HikariCP) with connection validation instead of manual caching
  4. Check isClosed() before reusing a cached connection

Example fix

// before
Connection conn = map.get("presto");
conn.createStatement().execute(query); // throws if conn was closed earlier
// after
try (Connection conn = DriverManager.getConnection(url, user, password)) {
    conn.createStatement().execute(query);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (conn == null || conn.isClosed()) {
    conn = DriverManager.getConnection(url, user, password);
}

Try / catch

try {
    stmt = conn.createStatement();
} catch (SQLException e) {
    if ("Connection is closed".equals(e.getMessage())) {
        conn = DriverManager.getConnection(url, user, password);
        stmt = conn.createStatement();
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling any method on a PrestoConnection after close() or abort() was called; using a connection returned from a pool that was already closed (double-close/double-checkout bug); keeping a long-lived connection past its idle timeout and reusing it after application-level close; using a connection after its backing session was killed.

Common situations: Connection-pool misconfiguration (stale/evicted connections handed out by cached pools like homegrown maps); forgetting to re-obtain a connection per request in long-running apps; closing a connection in a finally block and then using it again in later code; JDBC 4.1 try-with-resources variable referenced outside the try block.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/8134949a463ee957. Report an issue: GitHub.