aeron-io/aeron · error · ClusterException

invalid state counter code:

Error message

invalid state counter code: 

What it means

ClusterBackup.State.get(code) maps a cluster backup state counter value to its State enum. It throws ClusterException when the code is negative or beyond the last state, since no such state exists. The counter likely came from a different or incompatible Aeron version, or was corrupted.

Solutions

  1. Check the counter value being passed is the actual state value, not a counter ID or offset.
  2. Ensure all Aeron artifacts (client, cluster, archive) are the same version.
  3. Validate the code is within 0..State.values().length-1 before calling get().
  4. Re-read the counter from the correct CountersReader in case of corruption or a torn read.

Example fix

// before
State state = ClusterBackup.State.get(counterId); // wrong: ID, not value
// after
long value = counters.getCounterValue(counterId);
State state = (value >= 0 && value < State.values().length) ? ClusterBackup.State.get(value) : null;
Defensive patterns

Strategy: type-guard

Validate before calling

if (code < 0 || code >= ClusterBackup.State.values().length) { return null; }

Type guard

static ClusterBackup.State safeState(long code) { return (code >= 0 && code < ClusterBackup.State.values().length) ? ClusterBackup.State.get(code) : null; }

Try / catch

try {
    state = ClusterBackup.State.get(value);
} catch (ClusterException e) {
    log.error("unknown backup state counter value {}: version mismatch?", value);
}

Prevention

When it happens

Trigger: Calling ClusterBackup.State.get() with a counter value read from a CountersReader that is < 0 or >= STATES.length, e.g. reading the wrong counter ID or a counter from an incompatible Aeron version.

Common situations: Mixing Aeron client/cluster versions (counter layout changed), passing a counter ID instead of the counter value, or reading a stale/unregistered counter.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ClusterBackup.java:195

            if (counter.isClosed())
            {
                return CLOSED;
            }

            return get(counter.get());
        }

        /**
         * Get the {@link State} with matching {@link #code()}.
         *
         * @param code to lookup.
         * @return the {@link State} matching {@link #code()}.
         */
        public static State get(final long code)
        {
            if (code < 0 || code > (STATES.length - 1))
            {
                throw new ClusterException("invalid state counter code: " + code);
            }

            return STATES[(int)code];
        }
    }

    /**
     * Defines the type of node that this will receive log data from.
     */
    public enum SourceType
    {
        /**
         * Receive from any node in the cluster.
         */
        ANY,
        /**
         * Only receive data from the leader node.
         */

View on GitHub (pinned to 6d60124e15)