{"record":{"id":"f11ce6edf3df673f","repo":"prestodb/presto","slug":"iceberg-rollback-error","errorCode":"ICEBERG_ROLLBACK_ERROR","errorMessage":"Exception during rollback","messagePattern":"Exception during rollback","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-iceberg/src/main/java/com/facebook/presto/iceberg/delete/IcebergDeletePageSink.java","lineNumber":169,"sourceCode":"                dataFile,\n                POSITION_DELETES);\n\n        commitTasks.add(wrappedBuffer(jsonCodec.toJsonBytes(task)));\n\n        writtenBytes = writer.getWrittenBytes();\n        validationCpuNanos = writer.getValidationCpuNanos();\n\n        return completedFuture(commitTasks.build());\n    }\n\n    @Override\n    public void abort()\n    {\n        try {\n            positionDeleteWriter.getWriter().rollback();\n        }\n        catch (Throwable t) {\n            throw new PrestoException(ICEBERG_ROLLBACK_ERROR, \"Exception during rollback\");\n        }\n    }\n\n    private class IcebergPositionDeleteWriter\n    {\n        private final Schema positionDeleteSchema = new Schema(DELETE_FILE_PATH, DELETE_FILE_POS);\n        private final IcebergFileWriter writer;\n\n        public IcebergPositionDeleteWriter()\n        {\n            this.writer = createWriter();\n        }\n\n        /**\n         * @param page Only one channel. It contains the list of row positions to delete.\n         */\n        public void appendPage(Page page)\n        {","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-iceberg/src/main/java/com/facebook/presto/iceberg/delete/IcebergDeletePageSink.java#L151-L187","documentation":"When a delete sink is aborted, IcebergDeletePageSink rolls back the underlying position-delete file writer. If that rollback itself throws, the original abort failure is replaced by this ICEBERG_ROLLBACK_ERROR exception; the delete file may be left in an inconsistent/partial state.","triggerScenarios":"Calling abort() on the IcebergDeletePageSink when positionDeleteWriter.getWriter().rollback() fails — e.g. the writer was already closed, the underlying file handle/FS is broken, or the underlying writer threw its own exception earlier.","commonSituations":"Query failures triggering abort with an already-failed writer; HDFS/S3 connectivity problems during cleanup; double-abort paths.","solutions":["Inspect the swallowed cause: add the Throwable as the cause or log it to find the real rollback failure.","Ensure abort() is not called after close()/commit on the same writer.","Check filesystem permissions and connectivity for the delete-file location; orphan files can be cleaned via Iceberg's expire/cleanup procedures."],"exampleFix":"// before\nthrow new PrestoException(ICEBERG_ROLLBACK_ERROR, \"Exception during rollback\");\n// after\nthrow new PrestoException(ICEBERG_ROLLBACK_ERROR, \"Exception during rollback\", t); // keep root cause","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { sink.abort(); } catch (PrestoException e) { if (e.getErrorCode() == ICEBERG_ROLLBACK_ERROR.toErrorCode()) { /* schedule orphan-file cleanup; inspect writer state */ } throw e; }","preventionTips":["Never call abort() after close()/commit","Monitor filesystem health of the delete-file location","Run Iceberg orphan-file expiration regularly","Capture and log the rollback root cause"],"tags":["iceberg","delete-sink","rollback","io"],"backgroundTag":"rollback-failed","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}