aeron-io/aeron · error · ConfigurationException
recordingId must be set
Error message
recordingId must be set
What it means
PersistentSubscription.Builder.conclude() validates required fields and throws ConfigurationException("recordingId must be set") when recordingId is still Aeron.NULL_VALUE. A persistent subscription cannot be created without knowing which recording it consumes.
Solutions
- Call builder.recordingId(id) with a valid (non-NULL_VALUE) recording id before conclude()
- Obtain the recording id from AeronArchive.listRecording/listRecordingsForUri before building the subscription
- Validate configuration/arguments that supply the recording id early with a clear failure
- Start the recording first, capture the returned recordingId, then construct the persistent subscription
Example fix
// before PersistentSubscription.Builder b = new PersistentSubscription.Builder(); b.conclude(); // recordingId never set // after long recordingId = aeronArchive.startRecording(channel, streamId, LOCAL); b.recordingId(recordingId).liveChannel(liveChannel).liveStreamId(streamId); b.conclude();
Defensive patterns
Strategy: validation
Validate before calling
if (recordingId == Aeron.NULL_VALUE) {
throw new IllegalArgumentException("recordingId must be resolved before building PersistentSubscription");
} Type guard
boolean hasRecordingId(PersistentSubscription.Builder b) { return recordingId != Aeron.NULL_VALUE; } Try / catch
try {
builder.conclude();
} catch (ConfigurationException e) {
if (e.getMessage().equals("recordingId must be set")) {
throw new IllegalStateException("resolve recording id via AeronArchive before subscribing", e);
}
} Prevention
- Always fetch the recording id (startRecording/listRecordingsForUri) before building the subscription
- Fail fast when config/args yield a null/default recording id
- Use long primitives (not boxed Long) to avoid accidental NULL_VALUE defaults
- Add an assert on recordingId != Aeron.NULL_VALUE in setup code
When it happens
Trigger: Calling conclude() on a PersistentSubscription.Builder whose recordingId() was never called (or was set to Aeron.NULL_VALUE, e.g. from an unset/failed replay-destination lookup).
Common situations: Configuration code that conditionally sets recordingId but the condition failed silently; parsing a recording id from config/args returned null/default; initializing the subscription before the recording was actually started and its id obtained.
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
- liveStreamId 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/705b90522b4e764d.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/client/PersistentSubscription.java:1682
{
throw new RuntimeException(ex);
}
}
/**
* 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)View on GitHub (pinned to 6d60124e15)