aeron-io/aeron · error · ConfigurationException
liveStreamId must be set
Error message
liveStreamId must be set
What it means
PersistentSubscription.Builder.conclude() validates that liveStreamId was set and throws ConfigurationException("liveStreamId must be set") when it equals Aeron.NULL_VALUE. A persistent subscription needs the live stream id to follow the live stream once the recording's replay catches up.
Solutions
- Call builder.liveStreamId(streamId) with a valid stream id before conclude()
- Wire the same streamId used for the recording into the persistent subscription builder
- Validate config/CLI inputs so a missing stream id fails at parse time, not at conclude()
- Check builder call order — ensure no early return skips liveStreamId(...) setup
Example fix
// before b.recordingId(recordingId).liveChannel(liveChannel); b.conclude(); // liveStreamId missing // after b.recordingId(recordingId).liveChannel(liveChannel).liveStreamId(streamId); b.conclude();
Defensive patterns
Strategy: validation
Validate before calling
if (liveStreamId == Aeron.NULL_VALUE) {
throw new IllegalArgumentException("liveStreamId must be resolved before building PersistentSubscription");
} Type guard
boolean hasLiveStreamId(int streamId) { return streamId != Aeron.NULL_VALUE; } Try / catch
try {
builder.conclude();
} catch (ConfigurationException e) {
if (e.getMessage().equals("liveStreamId must be set")) {
throw new IllegalStateException("liveStreamId is required for a persistent subscription", e);
}
} Prevention
- Set every required builder field (recordingId, liveChannel, liveStreamId) in one helper so none is skipped
- Require streamId in configuration parsing rather than defaulting it
- Call conclude() only after all setters are verified
- Reuse the same stream id constants for recording and live follow
When it happens
Trigger: conclude() invoked on a builder where liveStreamId() was never called or set to Aeron.NULL_VALUE — recordingId and liveChannel may be fine, but the live follow stream id is missing.
Common situations: Builders configured from partial config files where only channel was provided and streamId was omitted; assuming liveStreamId has a default; copying builder setup code and dropping the liveStreamId line.
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
- recordingId must be set
- invalid fileIoMaxLength=
- catalogFileSyncLevel
- 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/6c6840cd4077cace.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/client/PersistentSubscription.java:1687
/**
* Conclude configuration by setting up defaults when specifics are not provided.
*/
@SuppressWarnings("MethodLength")
public void conclude()
{
if ((boolean)IS_CONCLUDED_VH.getAndSet(this, true))
{
throw new ConcurrentConcludeException();
}
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)View on GitHub (pinned to 6d60124e15)