aeron-io/aeron · error · ClusterException
counter is closed
Error message
counter is closed
What it means
ClusterControl.ToggleState.get throws ClusterException("counter is closed") when the control toggle AtomicCounter has been closed. A closed counter means the cluster container/control session has been torn down and its state can no longer be read.
Solutions
- Check controlToggle.isClosed() before calling get()
- Ensure you do not read cluster control state after Cluster/Archive container close()
- Fix lifecycle ordering so close happens only after all readers have stopped
Example fix
// before
ToggleState state = ClusterControl.ToggleState.get(controlToggle);
// after
if (!controlToggle.isClosed()) {
ToggleState state = ClusterControl.ToggleState.get(controlToggle);
} Defensive patterns
Strategy: type-guard
Validate before calling
// guard before reading boolean readable = controlToggle != null && !controlToggle.isClosed();
Type guard
boolean isOpen(AtomicCounter c) { return c != null && !c.isClosed(); } Try / catch
try {
ToggleState s = ClusterControl.ToggleState.get(controlToggle);
} catch (ClusterException e) {
// counter closed: cluster container has been torn down; stop reading
} Prevention
- Check isClosed() before every counter read in shutdown paths
- Coordinate close() ordering between conductor and service threads
- Avoid caching counter references past container lifecycle
When it happens
Trigger: Calling ClusterControl.ToggleState.get(controlToggle) after the AtomicCounter backing the control toggle was closed (e.g. after cluster shutdown or conductor teardown).
Common situations: Client code or tooling reading cluster control state during/after cluster shutdown, race between agent close and a service callback reading the toggle.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- client is closed
- Publication is closed
- response publication is closed: " + session
- client is closed
- counter id is not allocated, state
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/e32e5922c83f0231.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ClusterControl.java:169
* @param controlToggle to be deactivated.
*/
public static void deactivate(final AtomicCounter controlToggle)
{
controlToggle.set(INACTIVE.code());
}
/**
* 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.View on GitHub (pinned to 6d60124e15)