aeron-io/aeron · error · ClusterException

response publication already added

Error message

response publication already added

What it means

ClusterSession.connect creates the response publication wiring for a clustered session, but refuses to run if a responsePublication was already set. This is an internal lifecycle invariant: a session must not be connected twice, otherwise a second publication would be added for the same session and the first would leak.

Solutions

  1. Ensure sessions from the previous term are closed/disconnected before calling connect again.
  2. Check the prepareSessionsForNewTerm path only calls connect for sessions with a null responsePublication (sessions that need reconnection).
  3. If managing sessions directly, null out or discard the old session object and create a fresh one instead of reusing it.
  4. Report to Aeron maintainers if this occurs on the stock recovery path, as it indicates an internal invariant break.

Example fix

// before
session.connect(aeron, tempBuffer, clusterId); // session already connected
// after
if (null == session.responsePublication())
{
    session.connect(aeron, tempBuffer, clusterId);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (null != session.responsePublication()) { /* session already connected */ }

Type guard

boolean isConnectable(ClusterSession s) { return null == s.responsePublication(); }

Try / catch

try
{
    session.connect(aeron, tempBuffer, clusterId);
}
catch (ClusterException ex)
{
    if (!ex.getMessage().contains("response publication already added")) throw ex;
    // fall through: session already connected
}

Prevention

When it happens

Trigger: Calling connect(aeron, tempBuffer, clusterId) on a ClusterSession whose responsePublication field is non-null. In practice this happens when prepareSessionsForNewTerm runs connect on sessions that were not correctly disconnected/reset between terms.

Common situations: Cluster recovery or term-rollover paths where the previous term's sessions were not closed; a bug in lifecycle management when replaying/reusing sessions across leadership changes; custom code reusing a ClusterSession instance.

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

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ClusterSession.java:204

        closedLogPosition = AeronArchive.NULL_POSITION;
        closeReason = CloseReason.NULL_VAL;
    }

    void asyncConnect(final Aeron aeron, final MutableDirectBuffer tempBuffer, final int clusterId)
    {
        counterRegistrationId = addSessionCounter(aeron, tempBuffer, clusterId);
        responsePublicationId = aeron.asyncAddPublication(responseChannel, responseStreamId);
    }

    void connect(
        final ErrorHandler errorHandler,
        final Aeron aeron,
        final MutableDirectBuffer tempBuffer,
        final int clusterId)
    {
        if (null != responsePublication)
        {
            throw new ClusterException("response publication already added");
        }

        counterRegistrationId = addSessionCounter(aeron, tempBuffer, clusterId);

        try
        {
            responsePublication = aeron.addPublication(responseChannel, responseStreamId);
        }
        catch (final RegistrationException ex)
        {
            errorHandler.onError(new ClusterException(
                "failed to connect session response publication: " + ex.getMessage(), AeronException.Category.WARN));
        }
    }

    void disconnect(final Aeron aeron, final ErrorHandler errorHandler)
    {
        if (NULL_VALUE != responsePublicationId)

View on GitHub (pinned to 6d60124e15)