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

  1. Start the Db2 capture/ASN capture agent on the Db2 server (e.g. start the ASN capture program / asnqccmd START) so it records LSNs.
  2. Verify table registrations and capture status in SYSIBM replication tables (e.g. IBMQREP_CAPPARMS, capture status) and re-register tables if needed.
  3. Check the capture agent logs for crashes and restart it after any Db2 maintenance window.
  4. 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

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


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)