{"record":{"id":"ad43745061f116c6","repo":"apache/iceberg","slug":"interrupted-during-commit","errorCode":null,"errorMessage":"Interrupted during commit","messagePattern":"Interrupted during commit","errorType":"exception","errorClass":"UncheckedInterruptedException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/jdbc/JdbcTableOperations.java","lineNumber":142,"sourceCode":"    } catch (SQLTransientConnectionException | SQLNonTransientConnectionException e) {\n      throw new UncheckedSQLException(e, \"Database Connection failed\");\n    } catch (DataTruncation e) {\n      throw new UncheckedSQLException(e, \"Database data truncation error\");\n    } catch (SQLWarning e) {\n      throw new UncheckedSQLException(e, \"Database warning\");\n    } catch (SQLException e) {\n      if (JdbcUtil.isConstraintViolation(e)) {\n        if (currentMetadataLocation() == null) {\n          throw new AlreadyExistsException(e, \"Table already exists: %s\", tableIdentifier);\n        } else {\n          throw new UncheckedSQLException(e, \"Table already exists: %s\", tableIdentifier);\n        }\n      }\n\n      throw new UncheckedSQLException(e, \"Unknown failure\");\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new UncheckedInterruptedException(e, \"Interrupted during commit\");\n    }\n  }\n\n  private void updateTable(String newMetadataLocation, String oldMetadataLocation)\n      throws SQLException, InterruptedException {\n    int updatedRecords =\n        JdbcUtil.updateTable(\n            schemaVersion,\n            connections,\n            catalogName,\n            tableIdentifier,\n            newMetadataLocation,\n            oldMetadataLocation);\n\n    if (updatedRecords == 1) {\n      LOG.debug(\"Successfully committed to existing table: {}\", tableIdentifier);\n    } else {\n      throw new CommitFailedException(","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/jdbc/JdbcTableOperations.java#L124-L160","documentation":"The thread performing a JDBC catalog commit was interrupted while the underlying operation used interruptible connection/transaction helpers (JdbcUtil runs SQL inside Tasks with connection pools that may block). Iceberg re-asserts the interrupt flag and throws UncheckedInterruptedException so callers know the commit did not complete and its outcome is unknown.","triggerScenarios":"Executor shutdown / application teardown while a commit is in flight; Future.cancel(true) on a task running catalog.commit(); thread-pool rejection paths; query timeouts implemented via cancellation in the connection pool (e.g. HikariCP connection interruption).","commonSituations":"Spark job cancelled mid-commit; Flink checkpoint/commit thread interrupted at shutdown; test framework timeouts interrupting commit threads; Kubernetes pod terminating during commit.","solutions":["Let the commit retry after the interrupt: catch UncheckedInterruptedException, restore interrupt status, and re-attempt the commit once the thread pool is healthy","Verify the table's current metadata location after an interrupted commit to determine if it landed (commit may have succeeded before interruption)","Avoid cancelling commit threads abruptly; use catalog-level commit timeouts/retries instead","Ensure HikariCP/pool shutdown hooks don't interrupt in-flight connections during orderly shutdown"],"exampleFix":"// before\nexecutor.shutdownNow(); // may interrupt in-flight commits\n// after\nexecutor.shutdown();\nexecutor.awaitTermination(5, TimeUnit.MINUTES); // let commits drain before forcing interrupt","handlingStrategy":"try-catch","validationCode":"if (Thread.currentThread().isInterrupted()) { /* defer or abort commit before starting */ }","typeGuard":null,"tryCatchPattern":"try { table.newAppend().appendFile(f).commit(); } catch (UncheckedInterruptedException e) { Thread.currentThread().interrupt(); /* verify current metadata location, then retry if not landed */ }","preventionTips":["Gracefully shut down executors (shutdown + awaitTermination) instead of shutdownNow","Don't cancel futures wrapping catalog commits mid-flight","After interruption, refresh and check the table's metadata location before assuming the commit failed","Give commit threads adequate timeouts so pool shutdown rarely races them"],"tags":["jdbc","interrupt","concurrency","catalog-commit"],"backgroundTag":"request-timeout","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}