aeron-io/aeron · error · AeronException

Counter id is not allocated:

Error message

Counter id is not allocated: 

What it means

This Counter constructor wraps an existing counter by id and requires it to be in RECORD_ALLOCATED state in the CountersReader. If the id is unallocated or freed, the constructor throws immediately because a Counter cannot safely reference unallocated storage.

Solutions

  1. Verify the counter id with countersReader.getCounterState(id) == RECORD_ALLOCATED before constructing
  2. Obtain the id from the allocation call's return value (Counter allocated by CountersManager) rather than guessing
  3. Re-read the counter id from the current counters snapshot if the client reconnected
  4. Check that the counter wasn't freed (e.g. via counter.close() or driver reclaim) before use

Example fix

// before
Counter counter = new Counter(countersReader, savedId);

// after
if (countersReader.getCounterState(savedId) == CountersReader.RECORD_ALLOCATED)
{
    Counter counter = new Counter(countersReader, savedId);
}
else
{
    // re-allocate or look up the current id
}
Defensive patterns

Strategy: validation

Validate before calling

public static Counter safeCounter(CountersReader reader, int id) {
    if (reader.getCounterState(id) != CountersReader.RECORD_ALLOCATED) {
        throw new IllegalArgumentException("counter id " + id + " is not allocated");
    }
    return new Counter(reader, id);
}

Type guard

boolean isAllocated(CountersReader reader, int id) { return reader.getCounterState(id) == CountersReader.RECORD_ALLOCATED; }

Try / catch

try { Counter c = new Counter(countersReader, id); } catch (AeronException e) { if (e.getMessage().startsWith("Counter id is not allocated")) { id = relookupOrAllocateCounter(); } else { throw e; } }

Prevention

When it happens

Trigger: Constructing new Counter(countersReader, id) with an id that was never allocated, was already freed, or whose record state is RECLAIMED/unused; using a stale counter id captured before the counter was released.

Common situations: Reusing a counter id stored from a previous session; racing with another component that freed the counter; hard-coded or off-by-one counter ids; attaching to a driver whose counters were reset.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/667457584b31c0ac. Report an issue: GitHub.

Appendix: source

Thrown at aeron-client/src/main/java/io/aeron/Counter.java:80

        this.registrationId = registrationId;
        this.clientConductor = clientConductor;
        this.clientOwned = clientOwned;
    }

    /**
     * Construct a read-write view of an existing counter.
     *
     * @param countersReader for getting access to the buffers.
     * @param counterId      for the counter to be viewed.
     * @throws AeronException if the id has for the counter has not been allocated.
     */
    public Counter(final CountersReader countersReader, final int counterId)
    {
        super(countersReader.valuesBuffer(), counterId);

        if (countersReader.getCounterState(counterId) != CountersReader.RECORD_ALLOCATED)
        {
            throw new AeronException("Counter id is not allocated: " + counterId);
        }

        correlationId = Aeron.NULL_VALUE;
        registrationId = countersReader.getCounterRegistrationId(counterId);
        clientConductor = null;
        clientOwned = true;
    }

    /**
     * Return the correlation id of the counter creation command sent to the media driver.
     *
     * @return the correlation id of the command or {@link Aeron#NULL_VALUE} if unknown.
     */
    public long correlationId()
    {
        return correlationId;
    }

View on GitHub (pinned to 6d60124e15)