aeron-io/aeron · error · ArchiveException

ArchiveMarkFile headerLength=

Error message

ArchiveMarkFile headerLength=${headerLength} > headerLengthCapacity=${HEADER_LENGTH}

What it means

Thrown by ArchiveMarkFile during alignedTotalFileLength when the computed header length (derived from configured control channel/endpoint strings, recording events channel, and aeron directory name lengths) exceeds the fixed HEADER_LENGTH capacity of the mark file header. The archive refuses to start because it cannot persist its identity metadata in the fixed-size header.

Solutions

  1. Shorten the aeronDirectoryName (move the mark file/driver directory closer to the filesystem root).
  2. Shorten the archive's localControlChannel and recordingEventsChannel URIs (use IP addresses instead of long hostnames, drop unneeded parameters).
  3. Set aeron.archive.mark.file.header.length to a larger value if your build exposes the context override for it.
  4. Check for stale/oversized mark file config and clean the old archive directory if safe.

Example fix

// before
Archive.Context ctx = new Archive.Context()
    .aeronDirectoryName("/very/long/path/to/aeron/subsystem/dir/with/many/components")
    .localControlChannel("aeron:udp?endpoint=archive-control.very.long.internal.domain.example.com:8010");
// after
Archive.Context ctx = new Archive.Context()
    .aeronDirectoryName("/tmp/aeron")
    .localControlChannel("aeron:udp?endpoint=127.0.0.1:8010");
Defensive patterns

Strategy: validation

Validate before calling

String aeronDir = ctx.aeronDirectoryName();
String headerSources = ctx.localControlChannel().length() +
    (ctx.recordingEventsChannel() != null ? ctx.recordingEventsChannel().length() : 0) +
    aeronDir.length();
if (headerSources > 65536 /* expected safe budget; actual cap is ArchiveMarkFile.HEADER_LENGTH */) {
    throw new IllegalStateException("Archive mark file header inputs too long: " + headerSources);
}

Try / catch

try {
    archive = Archive.launch(ctx);
} catch (ArchiveException e) {
    if (e.getMessage().contains("headerLength=") && e.getMessage().contains("headerLengthCapacity=")) {
        // shorten aeronDirectoryName / channel URIs and relaunch
        ctx.aeronDirectoryName(Files.createTempDirectory("aeron").toString());
        archive = Archive.launch(ctx);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Starting an Archive with ArchiveMarkFileHeaderLength exceeding capacity, typically because the aeronDirectoryName or localControlChannel/recordingEventsChannel strings are very long (long paths, long hostnames/ports in endpoint URIs).

Common situations: Running in environments with deep/long temp directories (containers, CI) making aeronDirectoryName too long; very long control channel endpoint URIs with DNS names or IPv6 addresses; archive mark file version mismatch across configurations.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/b98933807b0e8389. Report an issue: GitHub.

Appendix: source

Thrown at aeron-archive/src/main/java/io/aeron/archive/ArchiveMarkFile.java:464

        {
            markFile.mappedByteBuffer().force();
        }
    }

    private static int alignedTotalFileLength(final Archive.Context ctx)
    {
        final int headerLength =
            HEADER_OFFSET +
            MarkFileHeaderEncoder.BLOCK_LENGTH +
            (4 * VarAsciiEncodingEncoder.lengthEncodingLength()) +
            (null != ctx.controlChannel() ? ctx.controlChannel().length() : 0) +
            ctx.localControlChannel().length() +
            (null != ctx.recordingEventsChannel() ? ctx.recordingEventsChannel().length() : 0) +
            ctx.aeronDirectoryName().length();

        if (headerLength > HEADER_LENGTH)
        {
            throw new ArchiveException(
                "ArchiveMarkFile headerLength=" + headerLength + " > headerLengthCapacity=" + HEADER_LENGTH);
        }

        final int filePageSize = null != ctx.aeron() ? ctx.aeron().context().filePageSize() :
            CommonContext.driverFilePageSize(
                new File(ctx.aeronDirectoryName()), ctx.epochClock(), new CommonContext().driverTimeoutMs());

        LogBufferDescriptor.checkPageSize(filePageSize);

        return BitUtil.align(HEADER_LENGTH + ctx.errorBufferLength(), filePageSize);
    }

    String aeronDirectory()
    {
        headerDecoder.sbeRewind();
        headerDecoder.skipControlChannel();
        headerDecoder.skipLocalControlChannel();
        headerDecoder.skipEventsChannel();

View on GitHub (pinned to 6d60124e15)