aeron-io/aeron · error · ConfigurationException
replayChannel must be set
Error message
replayChannel must be set
What it means
PersistentSubscription.Context.conclude() requires a replayChannel URI: the channel used to replay the recorded stream from the archive. If the configured replayChannel is null or empty, conclude() throws ConfigurationException. The subscription needs both a live and a replay path by design.
Solutions
- Set a valid channel URI via replayChannel("aeron:udp?endpoint=...") before conclude().
- If you do not need a distinct replay endpoint, reuse the live channel URI (with the replay streamId).
- Verify application config wiring supplies both channels.
Example fix
// before
ctx.liveChannel("aeron:udp?endpoint=localhost:10000");
ctx.liveStreamId(5);
ctx.conclude(); // throws: replayChannel must be set
// after
ctx.liveChannel("aeron:udp?endpoint=localhost:10000");
ctx.liveStreamId(5);
ctx.replayChannel("aeron:udp?endpoint=localhost:10001");
ctx.replayStreamId(7);
ctx.conclude(); Defensive patterns
Strategy: validation
Validate before calling
if (Strings.isEmpty(ctx.replayChannel())) {
throw new IllegalArgumentException("replayChannel must be set before conclude()");
} Try / catch
try {
ctx.conclude();
} catch (ConfigurationException e) {
// supply a default replay channel derived from the live channel
} Prevention
- Default the replayChannel to the liveChannel URI when no separate replay endpoint is needed.
- Validate both channels in a shared config-validation helper.
When it happens
Trigger: Calling conclude() without calling context.replayChannel(String), or passing null/empty. Typical when only the live channel/stream were configured or a replay-only parameter set was partially filled.
Common situations: Forgetting the replay channel while configuring a persistent (live-then-replay) subscription; null value read from application config; mixing up liveChannel/replayChannel setters so one is left unset.
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
- liveChannel must be set
- catalogFileSyncLevel
- invalid fileIoMaxLength=
- Archive.Context.controlChannel must be set
- Archive.Context.controlChannel must be UDP media: uri=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/b79745a629cb3bc9.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/client/PersistentSubscription.java:1697
if (Aeron.NULL_VALUE == recordingId)
{
throw new ConfigurationException("recordingId must be set");
}
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)View on GitHub (pinned to 6d60124e15)