{"record":{"id":"1aaed77ad56e0ee2","repo":"apache/seatunnel","slug":"post-sync-delete-rename-to-trash-failed-will-ret","errorCode":null,"errorMessage":"Post-sync delete: rename-to-trash failed, will retry: source={}","messagePattern":"Post-sync delete: rename-to-trash failed, will retry: source=(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/source/split/ContinuousMultipleTableFileSourceSplitEnumerator.java","lineNumber":747,"sourceCode":"            throws IOException {\n        String trashPath = buildDeleteStagingPath(op, checkpointId);\n        FileStatus trashedStatus = getFileStatusIfPresent(ctx.sourceFs, trashPath);\n        if (trashedStatus == null\n                && getFileStatusIfPresent(ctx.sourceFs, op.getSourcePath()) == null) {\n            log.info(\n                    \"Post-sync delete dropped: source and staged file are absent, source={}, \"\n                            + \"trash={}, checkpointId={}\",\n                    maskUriUserInfo(op.getSourcePath()),\n                    maskUriUserInfo(trashPath),\n                    checkpointId);\n            return OpCommitResult.SUCCESS;\n        }\n\n        if (trashedStatus == null) {\n            try {\n                ctx.sourceFs.renameFile(op.getSourcePath(), trashPath, false);\n            } catch (Exception e) {\n                log.warn(\n                        \"Post-sync delete: rename-to-trash failed, will retry: source={}\",\n                        maskUriUserInfo(op.getSourcePath()),\n                        e);\n                return OpCommitResult.FAILED_RETRYABLE;\n            }\n            trashedStatus = getFileStatusIfPresent(ctx.sourceFs, trashPath);\n        }\n\n        if (trashedStatus == null) {\n            // Another actor removed the staged file after rename. There is no source-side data\n            // left for this operation to protect.\n            log.info(\n                    \"Post-sync delete completed externally after staging: source={}, trash={}, \"\n                            + \"checkpointId={}\",\n                    maskUriUserInfo(op.getSourcePath()),\n                    maskUriUserInfo(trashPath),\n                    checkpointId);\n            return OpCommitResult.SUCCESS;","sourceCodeStart":729,"sourceCodeEnd":765,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/source/split/ContinuousMultipleTableFileSourceSplitEnumerator.java#L729-L765","documentation":"For a post-sync DELETE operation, if the file has not already been trashed, the enumerator attempts to rename the source file to a trash path. If that rename throws, it logs this warning with the sanitized source path and returns FAILED_RETRYABLE, leaving the file in place to retry later. The delete is only finalized once the rename to trash succeeds.","triggerScenarios":"ctx.sourceFs.renameFile(op.getSourcePath(), trashPath, false) fails — destination trash directory missing/unwritable, source file locked or removed by an external process, cross-filesystem rename not permitted, or transient FS/network error.","commonSituations":"Trash path not pre-created or lacking write permission; S3/HDFS hiccup during rename; concurrent external cleanup deleting the file mid-operation.","solutions":["Ensure the trash/target directory exists and the job user has write permission on it","Check the logged cause for rename failure and fix filesystem access or network issues","Verify no external process concurrently deletes or moves the source files managed by post-sync"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Before enabling post-sync delete, ensure the trash path parent exists and is writable\norg.apache.hadoop.fs.Path trashDir = trashPath.getParent();\nif (!fs.exists(trashDir)) {\n    fs.mkdirs(trashDir);\n}\nif (!fs.getFileStatus(trashDir).isDirectory()) {\n    throw new IllegalStateException(\"Trash dir is not a directory: \" + trashDir);\n}","typeGuard":null,"tryCatchPattern":"try {\n    ctx.sourceFs.renameFile(op.getSourcePath(), trashPath, false);\n} catch (Exception e) {\n    log.warn(\"Post-sync delete: rename-to-trash failed, will retry: source={}\",\n            maskUriUserInfo(op.getSourcePath()), e);\n    return OpCommitResult.FAILED_RETRYABLE;\n}","preventionTips":["Create the trash directory with correct permissions before enabling delete post-sync","Ensure rename stays within the same filesystem (same scheme/authority) so renames are atomic","Prevent external jobs from deleting/moving files managed by post-sync"],"tags":["file-connector","post-sync","delete","rename","filesystem"],"backgroundTag":"file-write-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}