{"record":{"id":"26e8bdf287362d20","repo":"apache/seatunnel","slug":"post-sync-backup-promoted-an-unexpected-target-ver","errorCode":null,"errorMessage":"Post-sync backup promoted an unexpected target version; operation will be retried: splitId={}, source={}, target={}, checkpointId={}","messagePattern":"Post-sync backup promoted an unexpected target version; operation will be retried: splitId=(.+?), source=(.+?), target=(.+?), checkpointId=(.+?)","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":945,"sourceCode":"        if (!isSinkTargetCommitted(ctx, op, checkpointId, stagingPath)) {\n            return handleRetryableStagedOperation(\n                    ctx, op, checkpointId, stagingPath, \"backup\", stagingStatus);\n        }\n\n        ctx.sourceFs.renameFile(stagingPath, op.getBackupTargetPath(), false);\n        targetStatus = getFileStatusIfPresent(ctx.sourceFs, op.getBackupTargetPath());\n        if (targetStatus == null) {\n            log.warn(\n                    \"Post-sync backup promotion target is absent after rename; operation will be retried: \"\n                            + \"splitId={}, source={}, target={}, checkpointId={}\",\n                    op.getSplitId(),\n                    maskUriUserInfo(op.getSourcePath()),\n                    maskUriUserInfo(op.getBackupTargetPath()),\n                    checkpointId);\n            return OpCommitResult.FAILED_RETRYABLE;\n        }\n        if (!isOperationContentMatched(ctx, op, op.getBackupTargetPath(), targetStatus)) {\n            log.warn(\n                    \"Post-sync backup promoted an unexpected target version; operation will be retried: \"\n                            + \"splitId={}, source={}, target={}, checkpointId={}\",\n                    op.getSplitId(),\n                    maskUriUserInfo(op.getSourcePath()),\n                    maskUriUserInfo(op.getBackupTargetPath()),\n                    checkpointId);\n            return OpCommitResult.FAILED_RETRYABLE;\n        }\n\n        log.info(\n                \"Post-sync backup completed: source={}, target={}, checkpointId={}, \"\n                        + \"capturedLen={}, capturedMtime={}\",\n                maskUriUserInfo(op.getSourcePath()),\n                maskUriUserInfo(op.getBackupTargetPath()),\n                checkpointId,\n                op.getSourceLength(),\n                op.getSourceModificationTime());\n        return OpCommitResult.SUCCESS;","sourceCodeStart":927,"sourceCodeEnd":963,"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#L927-L963","documentation":"After promoting the staged file to the backup target, the enumerator validates that the promoted content matches the captured source version (length+mtime, or a SHA-256 content fingerprint when available). This WARN fires when the target exists but does not match the expected version, so the operation returns FAILED_RETRYABLE rather than declaring success over wrong data. It guards against overwriting or mistaking another file's content as the backup.","triggerScenarios":"targetStatus is non-null after promotion but isOperationContentMatched() fails: the target's len/mtime differ from op.getSourceLength()/getSourceModificationTime(), or its SHA-256 fingerprint differs from op.getSourceContentFingerprint().","commonSituations":"The source file was modified by a writer after the operation captured its version, so the backup legitimately holds a different version; a previous attempt's differently-versioned file occupies the target path; fingerprint algorithm or encoding mismatch after a connector upgrade.","solutions":["Determine whether the source was rewritten concurrently; if so let the operation settle and re-check the versions in the log (expected vs actual len/mtime)","Remove the mismatched target file so a clean retry can promote the correct staged version","Enable/verify content fingerprinting (sourceContentFingerprint) so version checks are content-based instead of mtime-based, which is robust across filesystems","Check for connector version changes that altered the fingerprint computation between checkpoint save and restore"],"exampleFix":"null","handlingStrategy":"validation","validationCode":"// Compare content fingerprints before trusting a backup target\nString fp = sha256Hex(fs.open(targetPath));\nif (!fp.equals(op.getSourceContentFingerprint())) {\n    throw new IOException(\"Backup target version mismatch: \" + targetPath);\n}","typeGuard":null,"tryCatchPattern":"try {\n    verifyBackupContent(targetPath, expectedFingerprint);\n} catch (IOException | NoSuchAlgorithmException e) {\n    // treat as retryable mismatch; do not delete the source based on a bad target\n}","preventionTips":["Enable content fingerprinting so checks are content-based rather than len/mtime-based","Prevent concurrent writers from mutating source files during post-sync operations","Keep connector versions consistent between checkpoint save and restore (fingerprint algorithm)"],"tags":["hadoop","file-source","backup","checksum-mismatch","retryable"],"backgroundTag":"checksum-mismatch","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}