apache/seatunnel · error · java.lang.IllegalStateException

Data change record shouldn't use READ operation, the the rec

Error message

Data change record shouldn't use READ operation, the the record is %s.

What it means

During buffering of change records (rewriteOutputBuffer), JdbcSourceFetchTaskContext expects only INSERT/UPDATE/DELETE operations; a READ (snapshot-style) event appearing in the change buffer violates the incremental-phase contract, so it throws IllegalStateException. READ events are only valid during snapshot reading, not in the incremental output buffer where upsert semantics are applied.

Source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/base/source/reader/external/JdbcSourceFetchTaskContext.java:136

                    Instant fetchTs =
                            Instant.ofEpochMilli((Long) source.get(Envelope.FieldName.TIMESTAMP));
                    SourceRecord record =
                            new SourceRecord(
                                    changeRecord.sourcePartition(),
                                    changeRecord.sourceOffset(),
                                    changeRecord.topic(),
                                    changeRecord.kafkaPartition(),
                                    changeRecord.keySchema(),
                                    changeRecord.key(),
                                    changeRecord.valueSchema(),
                                    envelope.read(after, source, fetchTs));
                    outputBuffer.put(key, record);
                    break;
                case DELETE:
                    outputBuffer.remove(key);
                    break;
                case READ:
                    throw new IllegalStateException(
                            String.format(
                                    "Data change record shouldn't use READ operation, the the record is %s.",
                                    changeRecord));
            }
        }
    }

    @Override
    public List<SourceRecord> formatMessageTimestamp(Collection<SourceRecord> snapshotRecords) {
        return snapshotRecords.stream()
                .map(
                        record -> {
                            Envelope envelope = Envelope.fromSchema(record.valueSchema());
                            Struct value = (Struct) record.value();
                            Struct updateAfter = value.getStruct(Envelope.FieldName.AFTER);
                            // set message timestamp (source.ts_ms) to 0L
                            Struct source = value.getStruct(Envelope.FieldName.SOURCE);
                            source.put(Envelope.FieldName.TIMESTAMP, 0L);

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Check that incremental-snapshot (READ events) is not enabled in a way that leaks into the stream phase; align Debezium properties with the connector's expectations.
  2. Verify Debezium connector version compatibility with the SeaTunnel CDC connector version.
  3. Inspect the offending record (printed in the message) to see which table/operation produced the READ event and whether the source emitted it unexpectedly.
  4. Upgrade connector-cdc-base; known fixes adjusted event routing between snapshot and incremental phases.

Example fix

// before: buffer rewrite assumes only DML ops
switch (op) {
    case READ: throw new IllegalStateException(...);
}
// after: treat READ as an upsert (insert) at buffer level
case READ:
case INSERT:
    outputBuffer.put(key, record);
    break;
Defensive patterns

Strategy: validation

Validate before calling

// validate op before buffering
if (record.getOperation() == Operation.READ) {
    log.warn("READ event in incremental phase; route to snapshot handling");
}

Try / catch

try {
    fetcherContext.rewriteOutputBuffer(buffer, key, changeRecord);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("READ operation")) { /* handle snapshot-event leak */ }
}

Prevention

When it happens

Trigger: A data change event with operation READ (from Debezium's op=r or a snapshot event) reaches the incremental fetcher's output-buffer rewrite path, which handles INSERT/UPDATE/DELETE only.

Common situations: Connector bug where snapshot records leak into the incremental phase; Debezium signaling/incremental snapshot mode emitting READ events during streaming; custom fetcher configuration mixing snapshot and stream events; version mismatch between Debezium and the SeaTunnel CDC connector.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/219b0c47a306e867. Report an issue: GitHub.