aeron-io/aeron · error · IllegalArgumentException
Default header length not equal to HEADER_LENGTH: length=
Error message
Default header length not equal to HEADER_LENGTH: length={capacity} What it means
storeDefaultFrameHeader copies the per-publication default frame header into the log metadata buffer, and it must be exactly HEADER_LENGTH (32 bytes on Aeron) long. When defaultHeader.capacity() differs, an IllegalArgumentException is thrown because a wrong-sized header would corrupt the framing of every data frame written to the log.
Solutions
- Allocate the default header buffer with exactly LogBufferDescriptor.HEADER_LENGTH capacity (e.g. new UnsafeBuffer(ByteBuffer.allocateDirect(LogBufferDescriptor.HEADER_LENGTH)))
- Build the header via DataHeaderFlyweight.DEFAULT_HEADER_DEFAULT or DataHeaderFlyweight.createDefaultHeader(...) which produce correctly sized buffers
- Check defaultHeader.capacity() == LogBufferDescriptor.HEADER_LENGTH before calling storeDefaultFrameHeader
Example fix
// before final UnsafeBuffer header = new UnsafeBuffer(new byte[64]); LogBufferDescriptor.storeDefaultFrameHeader(metaBuffer, header); // after final UnsafeBuffer header = new UnsafeBuffer(ByteBuffer.allocateDirect(LogBufferDescriptor.HEADER_LENGTH)); LogBufferDescriptor.storeDefaultFrameHeader(metaBuffer, header);
Defensive patterns
Strategy: validation
Validate before calling
if (defaultHeader.capacity() != LogBufferDescriptor.HEADER_LENGTH) { throw new IllegalArgumentException("default header must be HEADER_LENGTH=" + LogBufferDescriptor.HEADER_LENGTH); } Try / catch
try { LogBufferDescriptor.storeDefaultFrameHeader(metaBuffer, defaultHeader); } catch (final IllegalArgumentException ex) { if (ex.getMessage().startsWith("Default header length not equal")) { /* rebuild header via DataHeaderFlyweight */ } throw ex; } Prevention
- Always build default headers with DataHeaderFlyweight.createDefaultHeader(...)
- Reference LogBufferDescriptor.HEADER_LENGTH instead of hard-coded sizes
- Re-check header construction after Aeron version upgrades
When it happens
Trigger: Calling LogBufferDescriptor.storeDefaultFrameHeader with a DirectBuffer whose capacity is not HEADER_LENGTH (e.g. 36 or 24 bytes), typically when constructing a custom default header for a Publication or when allocating the header buffer with the wrong constant.
Common situations: Custom protocol/instance-id headers built with DataHeaderFlyweight but sized incorrectly, refactoring that changed HEADER_LENGTH assumptions between Aeron versions, or manually sized UnsafeBuffer allocations.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Aeron spies are invalid as send destinations: channel=
- AeronArchive.Context.messageRetryAttempts must be > 0, got:
- applicationSpecificFeedback length must be equal to
- clientLivenessTimeoutNs=
- control has port=0 for subscription: channel=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/a6337eb5361f47c6.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-client/src/main/java/io/aeron/logbuffer/LogBufferDescriptor.java:841
* @return the total length of the log file.
*/
public static long computeLogLength(final int termLength, final int filePageSize)
{
return align((PARTITION_COUNT * (long)termLength) + LOG_META_DATA_LENGTH, filePageSize);
}
/**
* Store the default frame header to the log metadata buffer.
*
* @param metadataBuffer into which the default headers should be stored.
* @param defaultHeader to be stored.
* @throws IllegalArgumentException if the defaultHeader larger than {@link #LOG_DEFAULT_FRAME_HEADER_MAX_LENGTH}.
*/
public static void storeDefaultFrameHeader(final UnsafeBuffer metadataBuffer, final DirectBuffer defaultHeader)
{
if (defaultHeader.capacity() != HEADER_LENGTH)
{
throw new IllegalArgumentException(
"Default header length not equal to HEADER_LENGTH: length=" + defaultHeader.capacity());
}
metadataBuffer.putInt(LOG_DEFAULT_FRAME_HEADER_LENGTH_OFFSET, HEADER_LENGTH);
metadataBuffer.putBytes(LOG_DEFAULT_FRAME_HEADER_OFFSET, defaultHeader, 0, HEADER_LENGTH);
}
/**
* Get a wrapper around the default frame header from the log metadata.
*
* @param metadataBuffer containing the raw bytes for the default frame header.
* @return a buffer wrapping the raw bytes.
*/
public static UnsafeBuffer defaultFrameHeader(final UnsafeBuffer metadataBuffer)
{
return new UnsafeBuffer(metadataBuffer, LOG_DEFAULT_FRAME_HEADER_OFFSET, HEADER_LENGTH);
}
View on GitHub (pinned to 6d60124e15)