aeron-io/aeron · error · ClusterException

ingress publication is closed

Error message

ingress publication is closed

What it means

sendAdminRequestToTakeASnapshot offers an admin request on the ingress publication and polls the returned position. When the offer result equals Publication.CLOSED the publication has been closed and cannot accept messages, so the library throws ClusterException instead of silently failing to send the snapshot request.

Solutions

  1. Check AeronCluster.state()/connection liveness before issuing the admin request; reconnect with connect() if closed.
  2. Catch ClusterException and re-establish the cluster session before retrying the snapshot request.
  3. Synchronize client shutdown with code paths that send admin requests so they are not called concurrently with close().
  4. Investigate why the publication closed — session termination by the cluster (e.g. auth rejection) or explicit close().

Example fix

// before
cluster.sendAdminRequestToTakeASnapshot(); // throws if publication closed
// after
if (!cluster.isPublicationConnected()) { cluster.close(); cluster = AeronCluster.connect(ctx); }
cluster.sendAdminRequestToTakeASnapshot();
Defensive patterns

Strategy: validation

Validate before calling

if (!cluster.isPublicationConnected()) { cluster.close(); cluster = AeronCluster.connect(ctx.clone()); }

Try / catch

try { cluster.sendAdminRequestToTakeASnapshot(); } catch (ClusterException e) { if (e.getMessage().contains("ingress publication is closed")) { reconnectAndRetrySnapshot(); } }

Prevention

When it happens

Trigger: Calling AeronCluster.sendAdminRequestToTakeASnapshot() after the cluster session or ingress publication was closed — e.g. the client was closed on another thread, the cluster rejected/closed the session, or onNewLeader re-establishment closed the old publication.

Common situations: Triggering snapshots from admin tooling while the client is concurrently shut down; calling snapshot APIs after cluster connection loss; race between a session-close notification and an admin request.

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


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

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/client/AeronCluster.java:569

            if (position > 0)
            {
                adminRequestEncoder
                    .wrapAndApplyHeader(bufferClaim.buffer(), bufferClaim.offset(), messageHeaderEncoder)
                    .leadershipTermId(leadershipTermId)
                    .clusterSessionId(clusterSessionId)
                    .correlationId(correlationId)
                    .requestType(AdminRequestType.SNAPSHOT)
                    .putPayload(ArrayUtil.EMPTY_BYTE_ARRAY, 0, 0);

                bufferClaim.commit();

                return true;
            }

            if (position == Publication.CLOSED)
            {
                throw new ClusterException("ingress publication is closed");
            }

            if (position == Publication.MAX_POSITION_EXCEEDED)
            {
                throw new ClusterException("max position exceeded: term-length=" + publication.termBufferLength());
            }

            if (--attempts <= 0)
            {
                break;
            }

            idleStrategy.idle();
        }

        return false;
    }

View on GitHub (pinned to 6d60124e15)