aeron-io/aeron · error · ConfigurationException
replayStreamId must be set
Error message
replayStreamId must be set
What it means
conclude() checks that replayStreamId was set (i.e. not Aeron.NULL_VALUE). The replay stream id identifies the stream on the replayChannel used to deliver recorded data from the archive. Leaving it at the NULL_VALUE sentinel means the replay destination is incompletely specified, so a ConfigurationException is thrown.
Solutions
- Call replayStreamId(<positive int>) on the Context before conclude().
- If the same stream id is used for both paths, set it explicitly on both liveStreamId and replayStreamId.
- Ensure the config source supplying the replay stream id is present and parsed.
Example fix
// before
ctx.replayChannel("aeron:udp?endpoint=localhost:10001");
ctx.conclude(); // throws: replayStreamId must be set (still NULL_VALUE)
// after
ctx.replayChannel("aeron:udp?endpoint=localhost:10001");
ctx.replayStreamId(7);
ctx.conclude(); Defensive patterns
Strategy: validation
Validate before calling
if (Aeron.NULL_VALUE == ctx.replayStreamId()) {
throw new IllegalArgumentException("replayStreamId must be set before conclude()");
} Try / catch
try {
ctx.conclude();
} catch (ConfigurationException e) {
// fall back to liveStreamId if streams are shared
} Prevention
- Never rely on defaults for stream ids; set both liveStreamId and replayStreamId explicitly.
- Centralize stream id constants so live and replay ids are defined side by side.
When it happens
Trigger: conclude() called with replayStreamId never assigned (defaults to Aeron.NULL_VALUE), or explicitly set to Aeron.NULL_VALUE (-1).
Common situations: Setting liveStreamId and assuming it applies to replay too; forgetting the streamId setter while changing channels; programmatic construction where streamIds come from separate config keys and the replay one is missing.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- aeronArchiveContext must be set
- Archive.Context.controlChannel must be set
- Archive.Context.controlChannel must be UDP media: uri=
- Archive.Context.recordingEventsChannel must be set if…
- Archive.Context.replicationChannel must be set
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/53036fc820a9a305.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/client/PersistentSubscription.java:1702
if (Aeron.NULL_VALUE == liveStreamId)
{
throw new ConfigurationException("liveStreamId must be set");
}
if (Strings.isEmpty(liveChannel))
{
throw new ConfigurationException("liveChannel must be set");
}
if (Strings.isEmpty(replayChannel))
{
throw new ConfigurationException("replayChannel must be set");
}
if (Aeron.NULL_VALUE == replayStreamId)
{
throw new ConfigurationException("replayStreamId must be set");
}
if (null == aeronArchiveContext)
{
throw new ConfigurationException("aeronArchiveContext must be set");
}
if (null == listener)
{
listener = new NoOpPersistentSubscriptionListener();
}
if (0 > recordingId)
{
throw new ConfigurationException("invalid recordingId " + recordingId);
}
if (FROM_LIVE > startPosition)View on GitHub (pinned to 6d60124e15)