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

  1. Read the actual term length from the log metadata (LogBufferDescriptor.termLength on the metadata buffer) instead of assuming one, or pass a matching assumedTermLength.
  2. Clear the stale log directory so a fresh log is created with the current configuration.
  3. 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

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


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)