apache/kafka · error · UnsupportedOperationException

Magic versions prior to 2 do not support partition leader ep

Error message

Magic versions prior to 2 do not support partition leader epoch

What it means

Thrown by AbstractLegacyRecordBatch.setPartitionLeaderEpoch for any legacy batch (magic < 2). The partition leader epoch is an attribute only present in the v2 record-batch format (introduced in Kafka 0.11 / KIP-101); v0/v1 records have no field to store it. The method unconditionally throws because the operation is meaningless for the on-disk layout.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/record/internal/AbstractLegacyRecordBatch.java:500

            buffer.putLong(OFFSET_OFFSET, offset);
        }

        @Override
        public void setMaxTimestamp(TimestampType timestampType, long timestamp) {
            if (record.magic() == RecordBatch.MAGIC_VALUE_V0)
                throw new UnsupportedOperationException("Cannot set timestamp for a record with magic = 0");

            long currentTimestamp = record.timestamp();
            // We don't need to recompute crc if the timestamp is not updated.
            if (record.timestampType() == timestampType && currentTimestamp == timestamp)
                return;

            setTimestampAndUpdateCrc(timestampType, timestamp);
        }

        @Override
        public void setPartitionLeaderEpoch(int epoch) {
            throw new UnsupportedOperationException("Magic versions prior to 2 do not support partition leader epoch");
        }

        private void setTimestampAndUpdateCrc(TimestampType timestampType, long timestamp) {
            byte attributes = LegacyRecord.computeAttributes(magic(), compressionType(), timestampType);
            buffer.put(LOG_OVERHEAD + LegacyRecord.ATTRIBUTES_OFFSET, attributes);
            buffer.putLong(LOG_OVERHEAD + LegacyRecord.TIMESTAMP_OFFSET, timestamp);
            long crc = record.computeChecksum();
            ByteUtils.writeUnsignedInt(buffer, LOG_OVERHEAD + LegacyRecord.CRC_OFFSET, crc);
        }

        /**
         * LegacyRecordBatch does not implement this iterator and would hence fallback to the normal iterator.
         *
         * @return An iterator over the records contained within this batch
         */
        @Override
        public CloseableIterator<Record> skipKeyValueIterator(BufferSupplier bufferSupplier) {
            return CloseableIterator.wrap(iterator(bufferSupplier));

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Raise the topic's message.format.version to 2.0.0 or higher (kafka-topics --alter --config message.format.version=2.0) so new batches are v2 and carry leader epoch.
  2. Gate calls: only invoke setPartitionLeaderEpoch when batch.magic() >= RecordBatch.MAGIC_VALUE_V2.
  3. Re-produce the legacy segment into a v2-format topic to retire pre-0.11 data.

Example fix

// before
batch.setPartitionLeaderEpoch(epoch);

// after
if (batch.magic() >= RecordBatch.MAGIC_VALUE_V2) {
    batch.setPartitionLeaderEpoch(epoch);
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Before calling setPartitionLeaderEpoch:
if (batch.magic() < RecordBatch.MAGIC_VALUE_V2) {
    // leader epoch only exists on V2+ batches; skip
    return;
}

Type guard

// Guard: only V2 batches carry a partition leader epoch
static boolean supportsLeaderEpoch(RecordBatch b) {
    return b.magic() >= RecordBatch.MAGIC_VALUE_V2;
}

Try / catch

try {
    batch.setPartitionLeaderEpoch(epoch);
} catch (UnsupportedOperationException e) {
    // legacy batch (magic < 2); leader epoch not representable
}

Prevention

When it happens

Trigger: Calling setPartitionLeaderEpoch(int) on a batch whose magic is 0 or 1 — typically in the broker's log recovery / replication path (e.g., LogValidator.assignPartitionLeaderEpoch or LogManager recovery) when it encounters a v0/v1 segment.

Common situations: Mixed-format topics where some segments predate v2; broker restart on an old topic whose message.format.version is still 0.10.x; replication or log recovery operating against a legacy segment after a controller failover.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/034863e922c7f4aa.json. Report an issue: GitHub.