aeron-io/aeron · error · ArchiveException

when using startReplay with a response channel…

Error message

when using startReplay with a response channel, ReplayParams::subscriptionRegistrationId must be set

What it means

Thrown by startReplay with a response channel when ReplayParams.subscriptionRegistrationId is NULL_VALUE. When the replay is driven over a response channel, the client must tell the archive which local subscription (by registration id) the replay should be attached to; without it the request is invalid and cannot proceed.

Solutions

  1. Set ReplayParams.subscriptionRegistrationId to the registration id of the subscription added via Aeron.addSubscription for the replay channel
  2. If not using a response channel, use the plain startReplay path without a response-channel configuration
  3. Ensure the subscription is added before building ReplayParams so its registrationId is available

Example fix

// before
ReplayParams params = new ReplayParams();
// subscriptionRegistrationId left NULL
// after
long subRegId = aeron.addSubscription(replayChannel, replayStreamId).registrationId();
ReplayParams params = new ReplayParams();
params.subscriptionRegistrationId(subRegId);
Defensive patterns

Strategy: validation

Validate before calling

if (replayParams.subscriptionRegistrationId() == Aeron.NULL_VALUE) {
    throw new IllegalStateException("set ReplayParams.subscriptionRegistrationId before startReplay with a response channel");
}

Type guard

boolean replayParamsReady(ReplayParams p) { return p.subscriptionRegistrationId() != Aeron.NULL_VALUE; }

Prevention

When it happens

Trigger: Calling startReplay with a response-channel configuration while leaving ReplayParams.subscriptionRegistrationId unset (still Aeron NULL_VALUE).

Common situations: Developer adds a response channel but forgets to call ReplayParams.subscriptionRegistrationId(id) with the id returned by adding the replay subscription; copy-pasted replay params from a non-response-channel flow.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at aeron-archive/src/main/java/io/aeron/archive/client/AeronArchive.java:4307

        }
        catch (final Exception ex)
        {
            CloseHelper.close(replaySubscription);
            throw ex;
        }
    }

    private long startReplayViaResponseChannel(
        final long recordingId,
        final String replayChannel,
        final int replayStreamId,
        final ReplayParams replayParams)
    {
        lastCorrelationId = aeron.nextCorrelationId();

        if (NULL_VALUE == replayParams.subscriptionRegistrationId())
        {
            throw new ArchiveException(
                "when using startReplay with a response channel, ReplayParams::subscriptionRegistrationId must be set");
        }

        if (!archiveProxy.requestReplayToken(lastCorrelationId, controlSessionId, recordingId))
        {
            throw new ArchiveException("failed to send replay token request");
        }

        final long replayToken = pollForResponse(lastCorrelationId);

        replayParams.replayToken(replayToken);
        final ChannelUriStringBuilder uriBuilder = new ChannelUriStringBuilder(context.controlRequestChannel())
            .sessionId((Integer)null)
            .responseCorrelationId(replayParams.subscriptionRegistrationId())
            .termId((Integer)null).initialTermId((Integer)null).termOffset((Integer)null)
            .termLength(context.controlTermBufferLength())
            .spiesSimulateConnection(false);

View on GitHub (pinned to 6d60124e15)