aeron-io/aeron · error · ClusterException
invalid toggle value
Error message
invalid toggle value: ${toggleValue} What it means
ClusterControl.ToggleState.get validates that the counter's raw value indexes into the known STATES array; values below 0 or beyond the last state are rejected with this message. It indicates memory corruption, a version mismatch, or reading an uninitialised counter.
Solutions
- Verify all components use the same Aeron version
- Ensure the control toggle counter is initialised to a valid ToggleState ordinal before use
- Check nothing else writes into the counters buffer (buffer overrun/corruption)
- Log and clamp the raw value to diagnose which invalid value is produced
Example fix
// before
long v = toggle.get(); // may be -1 before init
// after
if (toggle.isClosed() || toggle.get() < 0 || toggle.get() >= ClusterControl.ToggleState.STATES.length) {
throw new IllegalStateException("toggle not initialised: " + toggle.get());
} Defensive patterns
Strategy: validation
Validate before calling
long v = controlToggle.get();
if (v < 0 || v >= ClusterControl.ToggleState.STATES.length) {
throw new IllegalStateException("toggle value out of range: " + v);
} Try / catch
try {
ToggleState s = ClusterControl.ToggleState.get(controlToggle);
} catch (ClusterException e) {
// dump raw value and component versions for corruption diagnosis
} Prevention
- Use identical Aeron versions across all members
- Initialise counters to a valid state before publication
- Guard the counters buffer from external writers
When it happens
Trigger: The AtomicCounter's value read via controlToggle.get() is < 0 or > STATES.length-1 (outside the 0..N toggle state range).
Common situations: Two nodes on different Aeron versions sharing a counter, an uninitialised/freshly allocated counter being read, or external writes to the counter buffer.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- existing max write time counter detected for archiveId=
- Counter id is not allocated:
- Log file length less than min length of : length=
- Counter not allocated: id=
- invalid errorBufferLength=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/359e8c3104158b7f.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ClusterControl.java:175
/**
* 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];
}
}
private ClusterControl()
{
}
/**
* Counter type id for the control toggle.
*/
public static final int CONTROL_TOGGLE_TYPE_ID = AeronCounters.CLUSTER_CONTROL_TOGGLE_TYPE_ID;
/**
* Map a {@link CountersReader} over the provided {@link File} for the CnC file.
*View on GitHub (pinned to 6d60124e15)