aeron-io/aeron · error · ClusterException

invalid toggle value

Error message

invalid toggle value: ${toggleValue}

What it means

NodeControl.ToggleState.get validates that the control-toggle counter holds a code in the range of valid ToggleState values (0..STATES.length-1). Values outside that range cannot map to a toggle state, so a ClusterException naming the value is thrown.

Solutions

  1. Only write documented ToggleState codes to the control counter
  2. Initialize/validate the counter value before first read
  3. Treat negative values as 'not set' and skip processing
  4. Make sure external tooling uses the same NodeControl.ToggleState codes as the cluster version

Example fix

// before
controlToggle.set(99); // arbitrary code
controlToggle.set(NodeControl.ToggleState.SUSPEND.code());
// after
controlToggle.set(NodeControl.ToggleState.SUSPEND.code());
Defensive patterns

Strategy: validation

Validate before calling

long v = counter.get(); if (v < 0 || v >= NodeControl.ToggleState.values().length) return null;

Type guard

boolean isValidToggle(long v) { return v >= 0 && v < NodeControl.ToggleState.values().length; }

Try / catch

try { ts = NodeControl.ToggleState.get(controlToggle); } catch (ClusterException e) { ts = ToggleState.NEUTRAL; }

Prevention

When it happens

Trigger: The control-toggle AtomicCounter was written with an out-of-range value (e.g. -1 from a NULL/initial value, or an arbitrary integer set by external tooling via the counters manager), then read by ToggleState.get.

Common situations: External monitoring tools or admin code writing to the cluster control counter; reading before the toggle was initialized; version mismatch where newer software defines more states than an old counter file implies.

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/e5722b3bf4df72a7. Report an issue: GitHub.

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/NodeControl.java:144

        /**
         * Get the {@link ToggleState} for a given control toggle.
         *
         * @param controlToggle to get the current state for.
         * @return the state for the current control toggle.
         * @throws ClusterException if the counter is not one of the valid values.
         */
        public static ToggleState get(final AtomicCounter controlToggle)
        {
            if (controlToggle.isClosed())
            {
                throw new ClusterException("counter is closed");
            }

            final long toggleValue = controlToggle.get();
            if (toggleValue < 0 || toggleValue > (STATES.length - 1))
            {
                throw new ClusterException("invalid toggle value: " + toggleValue);
            }

            return STATES[(int)toggleValue];
        }
    }

    /**
     * Counter type id for the control toggle.
     */
    public static final int CONTROL_TOGGLE_TYPE_ID = AeronCounters.NODE_CONTROL_TOGGLE_TYPE_ID;

    private NodeControl()
    {
    }

    /**
     * Find the control toggle counter or return null if not found.
     *

View on GitHub (pinned to 6d60124e15)