apache/iceberg · error · UncheckedInterruptedException

Interrupted in SQL query

Error message

Interrupted in SQL query

What it means

Thrown by JdbcUtil's exists-query helper when the thread waiting on the JDBC connection pool is interrupted. The code re-interrupts the thread (preserving the interrupt flag) and wraps the InterruptedException in UncheckedInterruptedException so callers see a runtime exception. It signals the existence check for a table/view/namespace was aborted mid-query, not that the entity is absent.

Source

Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcUtil.java:832

            try (PreparedStatement preparedStatement = conn.prepareStatement(sql)) {
              for (int pos = 0; pos < args.length; pos += 1) {
                preparedStatement.setString(pos + 1, args[pos]);
              }

              try (ResultSet rs = preparedStatement.executeQuery()) {
                if (rs.next()) {
                  return true;
                }
              }
            }

            return false;
          });
    } catch (SQLException e) {
      throw new UncheckedSQLException(e, "Failed to execute exists query: %s", sql);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new UncheckedInterruptedException(e, "Interrupted in SQL query");
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Retry the existence check in a fresh, non-interrupted thread after shutdown/cancellation completes
  2. Check whether your framework is cancelling the task (job kill, timeout) and avoid catalog calls during shutdown
  3. Increase connection pool / query timeout settings if long waits lead to cancellation
  4. Preserve and handle the interrupt: catch UncheckedInterruptedException at a higher level and stop work gracefully

Example fix

// before
boolean exists = catalog.tableExists(ident);
// after
try {
  boolean exists = catalog.tableExists(ident);
} catch (UncheckedInterruptedException e) {
  // thread was cancelled; re-check or propagate after executor settles
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: check interrupt status before catalog calls
if (Thread.currentThread().isInterrupted()) {
  throw new IllegalStateException("Thread interrupted before existence check");
}

Try / catch

try {
  boolean exists = catalog.tableExists(ident);
} catch (UncheckedInterruptedException e) {
  Thread.currentThread().interrupt();
  // abort or reschedule the work
}

Prevention

When it happens

Trigger: Calling JdbcCatalog.tableExists/viewExists/namespaceExists (which call the exists helper) while the current thread's interrupt flag is set or set during pool acquisition/query execution; typically task cancellation in Spark/Flink executors or executor shutdown.

Common situations: Query timeouts that cancel the running task, killing a Spark/Flink job mid-scan, application shutdown during catalog operations, or a thread pool being closed while catalog checks are still in flight.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/ecfae977659906ac. Report an issue: GitHub.