apache/seatunnel · warning
No maximum LSN recorded in Db2. Please ensure that the Db2…
Error message
No maximum LSN recorded in Db2. Please ensure that the Db2 capture agent is running
What it means
During the Db2 incremental (LSN-based) streaming phase, Db2TransactionLogFetchTask.execute polls dataConnection.getMaxLsn(); if Db2 reports no available maximum LSN, meaning the change-data capture agent has not recorded any change data, the task logs this warning, pauses via metronome, and continues polling in a loop instead of failing.
Solutions
- Start the Db2 capture/ASN capture agent on the Db2 server (e.g. start the ASN capture program / asnqccmd START) so it records LSNs.
- Verify table registrations and capture status in SYSIBM replication tables (e.g. IBMQREP_CAPPARMS, capture status) and re-register tables if needed.
- Check the capture agent logs for crashes and restart it after any Db2 maintenance window.
- Confirm your connector config (database/server) points at the instance where capture actually runs; the task resumes automatically once an LSN becomes available.
Example fix
-- before: capture agent stopped, connector loops on 'No maximum LSN recorded in Db2' -- after: start the capture agent on the Db2 server db2start asnqccmd START CAPTURE SERVER=<DB> CAPTURE_SCHEMA=ASN -- verify registrations exist so LSNs are recorded SELECT * FROM SYSIBM.IBMQREP_CAPPARMS;
Defensive patterns
Strategy: retry
Validate before calling
-- verify the capture agent is running before enabling incremental streaming SELECT CAPTURE_STATUS FROM SYSIBM.IBMQREP_CAPPARMS; -- and confirm tables are registered for capture
Type guard
null
Try / catch
// the task itself retries via metronome.pause(); wrap the streaming phase with a bounded alert
int noLsnWarnings = 0;
while (!maxLsnAvailable()) {
if (++noLsnWarnings > 30) {
alert("Db2 capture agent not producing LSNs — check ASN capture agent");
}
pause(pollInterval);
} Prevention
- Ensure the Db2 ASN capture agent is started and registered for your tables before switching to incremental reads.
- Monitor capture-agent health (SYSIBM capture tables) with external alerting.
- Restart the capture agent after Db2 maintenance windows or crashes.
- Point the connector at the Db2 instance where capture actually runs so LSNs are available.
When it happens
Trigger: The streaming loop runs while the Db2 ASN capture agent is stopped, not started for the monitored database, has crashed, or is registered but has captured nothing yet, so getMaxLsn() returns an unavailable Lsn.
Common situations: Db2 capture agent never started after enabling CDC on the tables; capture program stopped for maintenance or crashed; CDC enabled but capture not registered for the database being read; freshly provisioned CDC setup with no changes captured yet.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- ${e.getMessage()}
- not supported create new Offset by filename and position.
- Read the binlog offset error
- Can't obtain schema for table
- DB2 CDC table-names must use database.schema.table format…
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/b9714c9d4386b9a0.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-db2/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/db2/source/reader/fetch/transactionlog/Db2TransactionLogFetchTask.java:188
Metronome metronome = Metronome.sleeper(pollInterval, clock);
Queue<Db2ChangeTable> schemaChangeCheckpoints =
new PriorityQueue<>((x, y) -> x.getStopLsn().compareTo(y.getStopLsn()));
try {
AtomicReference<Db2ChangeTable[]> tablesSlot =
new AtomicReference<>(getCdcTablesToQuery(partition, offsetContext));
TxLogPosition lastProcessedPositionOnStart = offsetContext.getChangePosition();
long lastProcessedEventSerialNoOnStart = offsetContext.getEventSerialNo();
LOG.info(
"Last position recorded in offsets is {}[{}]",
lastProcessedPositionOnStart,
lastProcessedEventSerialNoOnStart);
TxLogPosition lastProcessedPosition = lastProcessedPositionOnStart;
boolean shouldIncreaseFromLsn = offsetContext.isSnapshotCompleted();
while (context.isRunning()) {
Lsn currentMaxLsn = dataConnection.getMaxLsn();
if (!currentMaxLsn.isAvailable()) {
LOG.warn(
"No maximum LSN recorded in Db2. Please ensure that the Db2 capture agent is running");
metronome.pause();
continue;
}
if (currentMaxLsn.equals(lastProcessedPosition.getCommitLsn())
&& shouldIncreaseFromLsn) {
metronome.pause();
continue;
}
Lsn fromLsn =
lastProcessedPosition.getCommitLsn().isAvailable()
&& shouldIncreaseFromLsn
? dataConnection.incrementLsn(
lastProcessedPosition.getCommitLsn())
: lastProcessedPosition.getCommitLsn();
shouldIncreaseFromLsn = true;
View on GitHub (pinned to cf67b549a7)