apache/seatunnel · warning
Post-sync delete: rename-to-trash failed, will retry: source
Error message
Post-sync delete: rename-to-trash failed, will retry: source={} What it means
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.
Source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-base/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/source/split/ContinuousMultipleTableFileSourceSplitEnumerator.java:747
throws IOException {
String trashPath = buildDeleteStagingPath(op, checkpointId);
FileStatus trashedStatus = getFileStatusIfPresent(ctx.sourceFs, trashPath);
if (trashedStatus == null
&& getFileStatusIfPresent(ctx.sourceFs, op.getSourcePath()) == null) {
log.info(
"Post-sync delete dropped: source and staged file are absent, source={}, "
+ "trash={}, checkpointId={}",
maskUriUserInfo(op.getSourcePath()),
maskUriUserInfo(trashPath),
checkpointId);
return OpCommitResult.SUCCESS;
}
if (trashedStatus == null) {
try {
ctx.sourceFs.renameFile(op.getSourcePath(), trashPath, false);
} catch (Exception e) {
log.warn(
"Post-sync delete: rename-to-trash failed, will retry: source={}",
maskUriUserInfo(op.getSourcePath()),
e);
return OpCommitResult.FAILED_RETRYABLE;
}
trashedStatus = getFileStatusIfPresent(ctx.sourceFs, trashPath);
}
if (trashedStatus == null) {
// Another actor removed the staged file after rename. There is no source-side data
// left for this operation to protect.
log.info(
"Post-sync delete completed externally after staging: source={}, trash={}, "
+ "checkpointId={}",
maskUriUserInfo(op.getSourcePath()),
maskUriUserInfo(trashPath),
checkpointId);
return OpCommitResult.SUCCESS;View on GitHub (pinned to cf67b549a7)
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
Defensive patterns
Strategy: retry
Validate before calling
// Before enabling post-sync delete, ensure the trash path parent exists and is writable
org.apache.hadoop.fs.Path trashDir = trashPath.getParent();
if (!fs.exists(trashDir)) {
fs.mkdirs(trashDir);
}
if (!fs.getFileStatus(trashDir).isDirectory()) {
throw new IllegalStateException("Trash dir is not a directory: " + trashDir);
} Try / catch
try {
ctx.sourceFs.renameFile(op.getSourcePath(), trashPath, false);
} catch (Exception e) {
log.warn("Post-sync delete: rename-to-trash failed, will retry: source={}",
maskUriUserInfo(op.getSourcePath()), e);
return OpCommitResult.FAILED_RETRYABLE;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Trash path not pre-created or lacking write permission; S3/HDFS hiccup during rename; concurrent external cleanup deleting the file mid-operation.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Post-sync operation failed and will be retried: action={}, s
- Dropping table %s exception.
- Skip post-sync staging because table context is not found. s
- Continuous discovery scan failed, will retry in next interva
- Failed to evaluate recovered split {}, re-enqueue it conserv
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/1aaed77ad56e0ee2.
Report an issue: GitHub.