aeron-io/aeron · error · ConfigurationException
logChannel must not contain
Error message
logChannel must not contain: <termId param name>
What it means
Part of the same validateLogChannel() check: the logChannel URI must not contain termId, since cluster members must agree on the log's term identity and a pinned termId would break replication/recovery. A ConfigurationException naming the parameter is thrown.
Solutions
- Remove termId from the logChannel URI.
- If term positioning is needed for other streams, configure it there, not on the cluster log channel.
- Let the cluster manage term parameters during election and replay.
Example fix
// before
ctx.logChannel("aeron:udp?endpoint=localhost:20000|termId=100");
// after
ctx.logChannel("aeron:udp?endpoint=localhost:20000"); Defensive patterns
Strategy: validation
Validate before calling
ChannelUri uri = ChannelUri.parse(logChannel);
if (uri.containsKey("termId")) {
throw new IllegalArgumentException("logChannel must not contain termId");
} Prevention
- Never pin termId on the cluster log channel
- Diff configured channels against known-good cluster samples
- Parse and whitelist allowed URI params before launch
When it happens
Trigger: logChannel URI includes termId, e.g. 'aeron:udp?endpoint=...|termId=100'.
Common situations: Copying a channel string from a standalone Aeron publication config; hand-crafted URI including term positioning params.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- logChannel must not contain
- logChannel must not contain
- Channel media type mismatch. When using…
- ClusterBackup.Context.catchupEndpoint must be set
- difference greater than 2^31 - 1: termId=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/5bde0cea2d3ea090.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/ConsensusModule.java:4618
}
else if (PriorityHeapTimerServiceSupplier.class.getName().equals(timeServiceClassName))
{
return new PriorityHeapTimerServiceSupplier();
}
throw new ClusterException("invalid TimerServiceSupplier: " + timeServiceClassName);
}
private void validateLogChannel()
{
final ChannelUri logChannelUri = parse(logChannel);
if (logChannelUri.containsKey(INITIAL_TERM_ID_PARAM_NAME))
{
throw new ConfigurationException("logChannel must not contain: " + INITIAL_TERM_ID_PARAM_NAME);
}
if (logChannelUri.containsKey(TERM_ID_PARAM_NAME))
{
throw new ConfigurationException("logChannel must not contain: " + TERM_ID_PARAM_NAME);
}
if (logChannelUri.containsKey(TERM_OFFSET_PARAM_NAME))
{
throw new ConfigurationException("logChannel must not contain: " + TERM_OFFSET_PARAM_NAME);
}
}
/**
* {@inheritDoc}
*/
@Override
public String toString()
{
return "ConsensusModule.Context" +
"\n{" +
"\n isConcluded=" + isConcluded() +
"\n ownsAeronClient=" + ownsAeronClient +
"\n aeronDirectoryName='" + aeronDirectoryName + '\'' +View on GitHub (pinned to 6d60124e15)