aeron-io/aeron · error · IllegalStateException
assumed term length does not match metadata: termLength=
Error message
assumed term length does not match metadata: termLength=
What it means
LogBuffers throws this IllegalStateException when the term length recorded in the log file's metadata buffer differs from the assumedTermLength the constructor was given. Aeron requires the mapped log's metadata to agree with the expected geometry; a mismatch means the file belongs to a different configuration or is corrupt.
Solutions
- Read the actual term length from the log metadata (LogBufferDescriptor.termLength on the metadata buffer) instead of assuming one, or pass a matching assumedTermLength.
- Clear the stale log directory so a fresh log is created with the current configuration.
- Make the channel term-length configuration consistent between the runs that produce and consume the log file.
Example fix
// before LogBuffers buffers = new LogBuffers(file, 1 << 20 /* assumed 1MB term */); // after AtomicBuffer metaBuffer = LogBufferDescriptor.metaDataBuffer(map); int actualTermLength = LogBufferDescriptor.termLength(metaBuffer); LogBuffers buffers = new LogBuffers(file, actualTermLength);
Defensive patterns
Strategy: validation
Validate before calling
int actualTermLength = LogBufferDescriptor.termLength(metaDataBuffer);
if (assumedTermLength != actualTermLength) {
assumedTermLength = actualTermLength; // adopt metadata value
} Try / catch
try {
return new LogBuffers(file, assumedTermLength);
} catch (IllegalStateException e) {
if (e.getMessage().contains("assumed term length")) {
return openWithMetadataTermLength(file); // re-read from metadata
}
throw e;
} Prevention
- Never hard-code term lengths when opening logs; read them from metadata.
- Keep aeron.term.length configuration stable across runs sharing a log directory.
- Clear stale log directories after configuration changes.
When it happens
Trigger: Reusing/replaying a log file created with a different aeron.term.length than the assumedTermLength passed to LogBuffers; attaching to a stale log from a previous run whose term length config changed; passing a wrong length constant when opening a read-only log.
Common situations: Changing term-length channel configuration between runs while reusing a persistent log directory; mixed client/library versions with different default term lengths pointing at the same log file; replay tools hard-coding a term length.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Log file length less than min length of : length=
- publication at max position: term-length=
- MTU greater than max message length for term length: mtu=
- term-length= does not match session-id tag value: channel=
- existing publication has different 'term-length': existing=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/2ed720323ac55ce1.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/LogBuffers.java:146
final MappedByteBuffer metaDataMappedBuffer = fileChannel.map(
mapMode, metaDataSectionOffset, metaDataMappingLength);
metaDataMappedBuffer.order(ByteOrder.LITTLE_ENDIAN);
mappedByteBuffers[LOG_META_DATA_SECTION_INDEX] = metaDataMappedBuffer;
logMetaDataBuffer = new UnsafeBuffer(
metaDataMappedBuffer,
(int)metaDataMappingLength - LOG_META_DATA_LENGTH,
LOG_META_DATA_LENGTH);
final int metaDataTermLength = LogBufferDescriptor.termLength(logMetaDataBuffer);
final int pageSize = LogBufferDescriptor.pageSize(logMetaDataBuffer);
checkPageSize(pageSize);
if (metaDataTermLength != assumedTermLength)
{
throw new IllegalStateException(
"assumed term length " + assumedTermLength +
" does not match metadata: termLength=" + metaDataTermLength);
}
termLength = assumedTermLength;
for (int i = 0; i < PARTITION_COUNT; i++)
{
final long position = assumedTermLength * (long)i;
final MappedByteBuffer mappedBuffer = fileChannel.map(mapMode, position, assumedTermLength);
mappedBuffer.order(ByteOrder.LITTLE_ENDIAN);
mappedByteBuffers[i] = mappedBuffer;
termBuffers[i] = mappedBuffer;
}
}
}
catch (final Exception ex)
{View on GitHub (pinned to 6d60124e15)