aeron-io/aeron · error · IllegalArgumentException
name + " cannot be negative: value=" + value
Error message
name + " cannot be negative: value=" + value
What it means
CatalogIndex.ensurePositive throws IllegalArgumentException when a caller passes a negative value for a catalog index operation argument (e.g. recording id, position or offset used by add, remove, or recordingOffset). The Aeron Archive catalog requires non-negative identifiers and offsets, so negative values are rejected up front with the offending name and value in the message.
Solutions
- Validate arguments are >= 0 before calling add/remove/recordingOffset and map -1 sentinels to explicit 'not found' handling instead of passing them through
- Check arithmetic that produces the value for underflow; clamp or throw a domain-specific error when a computed position/offset goes negative
- Log the value and its source at the call site to find where the negative value originates
- Verify external inputs (config files, control requests, replay parameters) are parsed and range-checked before reaching the catalog index
Example fix
// before
long offset = stopPosition - startPosition; // can be negative if stop < start
catalogIndex.recordingOffset(recordingId, offset);
// after
long offset = stopPosition - startPosition;
if (offset < 0) { throw new IllegalArgumentException("stopPosition < startPosition for recordingId=" + recordingId); }
catalogIndex.recordingOffset(recordingId, offset); Defensive patterns
Strategy: validation
Validate before calling
if (recordingId < 0) { throw new IllegalArgumentException("recordingId must be non-negative, got " + recordingId); }
if (offset < 0) { throw new IllegalArgumentException("offset must be non-negative, got " + offset); }
catalogIndex.recordingOffset(recordingId, offset); Type guard
static boolean isNonNegative(long v) { return v >= 0L; } Try / catch
try { catalogIndex.remove(recordingId); }
catch (IllegalArgumentException e) { if (e.getMessage().contains("cannot be negative")) { /* map to caller error */ } else { throw e; } } Prevention
- Never pass -1 sentinel values from failed lookups into catalog index calls
- Range-check all recording ids, positions, and offsets at API boundaries
- Unit-test subtraction-based position math for underflow
- Validate parsed external config/request values before use
When it happens
Trigger: Calling CatalogIndex.add, remove, or recordingOffset with a negative long argument, typically a recordingId, startPosition, or offset computed from a failed lookup (e.g. -1 sentinel) or an underflowed subtraction.
Common situations: Passing a -1 sentinel value returned by a failed recording-id lookup; subtracting positions where the minuend is smaller than the subtrahend; uninitialized long fields defaulted incorrectly; deserializing corrupt control or configuration values.
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
- Invalid errorBufferLength
- gapLength must be smaller than gapRadix
- invalid fileIoMaxLength=
- incompatible catalog file version " +…
- unknown recording id: " + recordingId
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/4c7b2010b0a7ecf0.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/CatalogIndex.java:221
}
return -1;
}
private static long[] expand(final long[] index)
{
final int length = index.length;
final int entries = length >> 1;
final int newLength = (entries + (entries >> 1)) << 1;
return copyOf(index, newLength);
}
private static void ensurePositive(final long value, final String name)
{
if (value < 0L)
{
throw new IllegalArgumentException(name + " cannot be negative: value=" + value);
}
}
}
View on GitHub (pinned to 6d60124e15)