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
- 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.
- Gate calls: only invoke setPartitionLeaderEpoch when batch.magic() >= RecordBatch.MAGIC_VALUE_V2.
- 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
- Partition leader epoch is a V2-only concept; never call setPartitionLeaderEpoch on V0/V1 batches.
- Migrate topics to message.format.version >= 2.0 (or rely on KRaft defaults) if you depend on epoch-tagged records.
- Branch on magic() before any V2-specific mutation.
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
- Found invalid wrapper offset in compressed v1 message set, w
- Cannot set timestamp for a record with magic = 0
- Invalid leader epoch {leaderEpoch} (must be non-negative)
- Record size is less than the minimum record overhead (%d)
- Record size exceeds the largest allowable message size (%d).
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/034863e922c7f4aa.json.
Report an issue: GitHub.