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
- Shorten the aeronDirectoryName (move the mark file/driver directory closer to the filesystem root).
- Shorten the archive's localControlChannel and recordingEventsChannel URIs (use IP addresses instead of long hostnames, drop unneeded parameters).
- Set aeron.archive.mark.file.header.length to a larger value if your build exposes the context override for it.
- 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
- Keep aeronDirectoryName short; avoid deeply nested temp paths in containers and CI.
- Use concise endpoint URIs (IPs, no long DNS suffixes) for localControlChannel and recordingEventsChannel.
- Pin a common archive version/config across nodes so header layout expectations stay consistent.
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
- invalid errorBufferLength=
- catalogFileSyncLevel
- invalid fileIoMaxLength=
- Archive.Context.controlChannel must be set
- Archive.Context.controlChannel must be UDP media: uri=
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)