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
- Set ReplayParams.subscriptionRegistrationId to the registration id of the subscription added via Aeron.addSubscription for the replay channel
- If not using a response channel, use the plain startReplay path without a response-channel configuration
- 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
- Always set subscriptionRegistrationId when using a response channel
- Add a pre-call assertion in helper wrappers around startReplay
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
- failed to offer async replay response
- failed to send replay token request
- timed out wait for replay publication to connect
- timed out waiting for replay connection to have available…
- liveChannel must be set
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)