apache/seatunnel · error
fetch data failed.
Error message
fetch data failed.
What it means
IncrementalSourceSplitReader.fetch() polls CDC records from the current incremental fetcher. If pollSplitRecords() throws InterruptedException or SeaTunnelException, it logs 'fetch data failed.' and wraps the cause in an IOException, which fails the source reader and ultimately the job. This is a transport/connector-level failure of the CDC record poll loop.
Solutions
- Inspect the wrapped cause (IOException.getCause()) for the root database error and fix accordingly (connectivity, credentials, binlog).
- Ensure binlog retention (expire_logs_days / binlog_expire_logs_seconds) is long enough to cover pause/backlog; restart from a valid checkpoint.
- Add retry/resume from checkpoint: rerun the job from its last savepoint/checkpoint rather than scratch.
- Verify database user still has REPLICATION SLAVE/CLIENT and SELECT privileges.
- Increase network timeouts / keepalives between the SeaTunnel worker and the database.
Defensive patterns
Strategy: retry
Validate before calling
// before submitting: verify connectivity and privileges // mysql -h host -u cdc_user -p -e "SHOW GRANTS FOR CURRENT_USER;" // and check: SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';
Try / catch
try {
reader.pollSplitRecords();
} catch (IOException e) {
Throwable cause = e.getCause();
if (cause instanceof InterruptedException) {
// expected on cancel — do not retry
} else {
// transient DB/network error — retry with backoff from checkpoint
}
} Prevention
- Set binlog retention well beyond expected job downtime
- Use stable network paths / increase TCP keepalive for long CDC connections
- Monitor and re-run from checkpoints instead of restarting from scratch
- Keep CDC user privileges (REPLICATION SLAVE, SELECT) stable across the run
When it happens
Trigger: pollSplitRecords() throws while reading from the upstream database log (MySQL binlog, etc.): connection drop to the database, binlog position no longer available (binlog purged/GTID gap), timeout, or the underlying Debezium fetcher erroring during snapshot/streaming. Interrupted while blocking on the poll (task cancellation).
Common situations: Database restarted or network blip between worker and MySQL; binlog files purged before the reader caught up; user permissions revoked mid-run (binlog access lost); firewall/load-balancer idle timeout killing long-lived CDC connection; job cancelled leading to InterruptedException.
Related errors
- Edge transport IO failure, will reconnect. batchId=
- Failed to execute HTTP request to Firebase endpoint
- Failed to publish NATS JetStream message for subtask
- RABBITMQ-02
- RABBITMQ-04
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/b1a76f482089f73d.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/base/source/reader/IncrementalSourceSplitReader.java:93
this.splits = new ArrayDeque<>();
this.dataSourceDialect = dataSourceDialect;
this.sourceConfig = sourceConfig;
this.schemaChangeResolver = schemaChangeResolver;
}
@Override
public RecordsWithSplitIds<SourceRecords> fetch() throws IOException {
checkSplitOrStartNext();
checkNeedStopBinlogReader();
if (hasEmittedCurrentSplitFinished()) {
return NoSplitRecords.INSTANCE;
}
Iterator<SourceRecords> dataIt = null;
try {
dataIt = currentFetcher.pollSplitRecords();
} catch (InterruptedException | SeaTunnelException e) {
log.warn("fetch data failed.", e);
throw new IOException(e);
}
if (dataIt == null) {
return finishedSnapshotSplit();
}
if (currentSplitId == null) {
log.warn(
"Invalid state: currentSplitId is null when emitting records. "
+ "emittedFinishedSplitId={}, currentFetcher={}, isFinished={}",
emittedFinishedSplitId,
currentFetcher != null ? currentFetcher.getClass().getSimpleName() : "null",
currentFetcher != null && currentFetcher.isFinished());
throw new IOException(
String.format(
"Invalid state: currentSplitId is null when emitting records. "
+ "emittedFinishedSplitId=%s, currentFetcher=%s, isFinished=%s",
emittedFinishedSplitId,
currentFetcher != nullView on GitHub (pinned to cf67b549a7)