apache/seatunnel · warning
Skipping checkpoint batch because none of its transactions r
Error message
Skipping checkpoint batch because none of its transactions remain in the XA recovery scan; treating it as already resolved: {} What it means
During restoreCommit, JdbcSinkAggregatedCommitter.replayRecoveredCheckpoint() replays checkpointed XA transactions against the set of transactions still found in the database's XA recovery scan (xa_recover). If NONE of the checkpoint's XIDs appear in the recovery scan, the code assumes they were already committed/resolved and skips the batch, logging this WARN.
Source
Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSinkAggregatedCommitter.java:214
}
return normalized;
}
/**
* Replays one restored checkpoint using the recovery scan as evidence for which transactions
* can still be committed safely.
*
* @param checkpointXids checkpoint-owned prepared transactions in original commit order
* @param recoveredXids canonical values returned by the resource manager recovery scan
*/
private void replayRecoveredCheckpoint(
List<XidInfo> checkpointXids, Set<XidKey> recoveredXids) {
if (checkpointXids.isEmpty()) {
return;
}
int firstRecoveredIndex = findFirstRecoveredIndex(checkpointXids, recoveredXids);
if (firstRecoveredIndex < 0) {
log.warn(
"Skipping checkpoint batch because none of its transactions remain in the XA recovery scan; treating it as already resolved: {}",
checkpointXids);
return;
}
List<XidInfo> stillPrepared = new ArrayList<>();
for (int i = firstRecoveredIndex; i < checkpointXids.size(); i++) {
XidInfo xidInfo = checkpointXids.get(i);
if (!containsEquivalentXid(recoveredXids, xidInfo.getXid())) {
throw new JdbcConnectorException(
CommonErrorCodeDeprecated.WRITER_OPERATION_FAILED,
String.format(
"checkpoint transaction %s is absent from the XA recovery scan after still-prepared transactions in the same commit batch: %s",
xidInfo.getXid(), checkpointXids));
}
stillPrepared.add(xidInfo);
}
commitXidInfos(stillPrepared);
if (firstRecoveredIndex > 0) {View on GitHub (pinned to cf67b549a7)
Solutions
- Verify the recovery connection uses the same user/DB so xa_recover returns the transactions
- Check whether an earlier recovery pass already committed these Xids (expected, benign)
- If Xids are being purged prematurely, extend the DB's orphan-transaction retention / max_commit_timeout
- Inspect the DB for lost XA records and rely on downstream idempotency
Defensive patterns
Strategy: try-catch
Validate before calling
// before restore, list what recovery sees
Set<String> recovered = xaFacade.recover().stream()
.map(x -> new String(x.getGlobalTransactionId(), UTF_8))
.collect(Collectors.toSet());
checkpointXids.forEach(x -> {
if (!recovered.contains(keyOf(x)))
log.info("Xid {} not in recovery scan; presumed resolved", x);
}); Try / catch
try {
committer.restoreCommit(checkpointXids);
} catch (TransientXaException e) {
log.warn("Recovery scan failed; retry with backoff", e);
} Prevention
- Use the same DB user for recovery as for commit
- Keep idempotent sinks/downstream dedup
- Extend orphan XA retention in the database
When it happens
Trigger: Restoring a job from checkpoint whose checkpointed Xids are absent from xa_recover — e.g. transactions were resolved by a previous recovery run, the XA record expired/was purged, or the recovery scan hits a different user/database.
Common situations: Job restarted after crash; database cleanup jobs purging orphaned XA transactions; connecting with credentials lacking rights to see other users' XIDs; max_retry_timeout exceeded and externally committed.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Skipping {} checkpoint transactions that are absent from the
- Failed to get all checkpoints for job ${jobId}
- ${ExceptionUtils.getMessage(e)}
- No checkpoint found, job(${jobId}), pipeline(${pipelineId}),
- rollback {} recovered transactions
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/705b8cf994e4d2e7.
Report an issue: GitHub.