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

  1. Set the catalog capacity to at least MIN_CAPACITY (a few KB) and at most MAX_CATALOG_LENGTH as defined in Catalog.java
  2. Check where the value comes from (CLI flag, system property, config) and ensure a valid numeric value is supplied
  3. Use Archive.Configuration.MAX_CATALOG_CAPACITY default or omit the setting to let Aeron pick a valid default
  4. 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

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


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)