aeron-io/aeron · error · IllegalArgumentException
Invalid catalog capacity provided: expected value >= " +…
Error message
Invalid catalog capacity provided: expected value >= " + MIN_CAPACITY + ", got " + catalogCapacity
What it means
Thrown by Catalog.validateCapacity when the requested catalog file capacity is outside the allowed range: below MIN_CAPACITY or above MAX_CATALOG_LENGTH. The catalog file must be large enough for its page-size header/entries yet addressable within the catalog's internal offset limits. This is an IllegalArgumentException raised during archive catalog construction, so it fails fast at startup.
Solutions
- Set the catalog capacity to at least MIN_CAPACITY (a few KB) and at most MAX_CATALOG_LENGTH as defined in Catalog.java
- Check where the value comes from (CLI flag, system property, config) and ensure a valid numeric value is supplied
- Use Archive.Configuration.MAX_CATALOG_CAPACITY default or omit the setting to let Aeron pick a valid default
- Validate the value in your own config loader before passing it to Archive.Context.maxCatalogCapacity
Example fix
// before
context.maxCatalogCapacity(Long.parseLong(System.getProperty("aeron.archive.catalog.capacity", "0")));
// after
long capacity = Long.parseLong(System.getProperty("aeron.archive.catalog.capacity",
String.valueOf(Archive.Configuration.MAX_CATALOG_CAPACITY_DEFAULT)));
context.maxCatalogCapacity(Math.max(Catalog.MIN_CAPACITY, capacity)); Defensive patterns
Strategy: validation
Validate before calling
long capacity = configuredCatalogCapacity;
if (capacity < Catalog.MIN_CAPACITY || capacity > Catalog.MAX_CATALOG_LENGTH) {
throw new IllegalArgumentException("catalog capacity " + capacity +
" outside valid range [" + Catalog.MIN_CAPACITY + ", " + Catalog.MAX_CATALOG_LENGTH + "]");
} Try / catch
try {
context.maxCatalogCapacity(parseCapacity(config));
} catch (IllegalArgumentException e) {
log.warn("Invalid catalog capacity, falling back to default", e);
context.maxCatalogCapacity(Archive.Configuration.MAX_CATALOG_CAPACITY_DEFAULT);
} Prevention
- Validate numeric CLI/config values before passing them to Archive.Context
- Never pass unvalidated Long.parseLong results (0/negative on failure) as capacities
- Check units (bytes not KB/MB) when computing capacity
- Use the library defaults unless you have a specific capacity requirement
When it happens
Trigger: Calling CatalogTool or Archive.Context with a catalog capacity < MIN_CAPACITY (e.g. 0 or negative, or an unparseable CLI arg defaulting to 0) or greater than MAX_CATALOG_LENGTH when constructing a Catalog or configuring archiveCatalogCapacity().
Common situations: Typo'd CLI flag (e.g. --max-catalog-capacity 0); computing capacity from an unset config value that resolves to 0; copy-pasting a capacity in the wrong unit (KB vs bytes) yielding a huge number; passing bytes-per-recording instead of total catalog size.
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
- catalogFileSyncLevel
- invalid fileIoMaxLength=
- Archive.Context.controlChannel must be set
- Archive.Context.controlChannel must be UDP media: uri=
- local control channel must be IPC media: uri=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/f02e0060c9814e0f.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/Catalog.java:931
return checksum.compute(
catalogByteBufferAddress,
DESCRIPTOR_HEADER_LENGTH + recordingDescriptorOffset,
recordingLength);
}
return 0;
}
void catalogResized(final long oldCapacity, final long newCapacity)
{
ArchiveTracing.traceCatalogResize(oldCapacity, newCapacity);
}
private static void validateCapacity(final long catalogCapacity)
{
if (catalogCapacity < MIN_CAPACITY || catalogCapacity > MAX_CATALOG_LENGTH)
{
throw new IllegalArgumentException("Invalid catalog capacity provided: expected value >= " +
MIN_CAPACITY + ", got " + catalogCapacity);
}
}
private void initBuffers(final MappedByteBuffer catalogMappedByteBuffer)
{
catalogByteBuffer = catalogMappedByteBuffer;
catalogByteBuffer.order(BYTE_ORDER);
catalogBuffer = new UnsafeBuffer(catalogByteBuffer);
catalogByteBufferAddress = catalogBuffer.addressOffset();
fieldAccessBuffer = new UnsafeBuffer(catalogByteBuffer);
headerAccessBuffer = new UnsafeBuffer(catalogByteBuffer);
}
private void buildIndex(final boolean writable)
{
final int endOffset = (int)capacity;
int offset = firstRecordingDescriptorOffset;View on GitHub (pinned to 6d60124e15)