aeron-io/aeron · error · ClusterException
expected schemaId=<MessageHeaderDecoder.SCHEMA_ID>, actual=
Error message
expected schemaId=<MessageHeaderDecoder.SCHEMA_ID>, actual=<schemaId>
What it means
EgressAdapter.onFragment decoded the SBE MessageHeader of an egress fragment and found a schemaId that does not match the cluster egress schema (MessageHeaderDecoder.SCHEMA_ID). It throws ClusterException since decoding with the compiled codecs would be unsafe.
Solutions
- Align aeron-cluster versions between client and cluster
- Check that the subscription points at the correct egress streamId/channel
- Regenerate codecs from the matching schema if customized
- Inspect the unexpected schemaId to trace the actual producer of the fragment
Example fix
// before AeronCluster.connect(new AeronCluster.Context()); // cluster on different schema version // after // pin both sides to the same aeron-cluster release before reconnecting
Defensive patterns
Strategy: validation
Validate before calling
MessageHeaderDecoder h = new MessageHeaderDecoder().wrap(buffer, offset);
if (h.schemaId() != MessageHeaderDecoder.SCHEMA_ID) {
// handle mismatch before calling EgressAdapter.onFragment
} Try / catch
try {
adapter.onFragment(buffer, offset, length, header);
} catch (ClusterException ex) {
// log and skip incompatible fragment
} Prevention
- Keep client and cluster SBE codecs from the same release
- Validate subscription endpoints during integration tests
- Track schemaId in diagnostics when upgrading
When it happens
Trigger: Subscribing to a stream carrying a different SBE schema than aeron cluster egress; version mismatch between client and cluster SBE codecs.
Common situations: Mixed Aeron versions after upgrade; wrong subscription channel/stream wiring; custom protocols reusing the egress stream.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- expected schemaId=<MessageHeaderDecoder.SCHEMA_ID>, actual=
- expected schemaId= , actual=
- expected schemaId=<MessageHeaderDecoder.SCHEMA_ID>, actual=
- expected schemaId= , actual=
- expected schemaId= , actual=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/d5263b73dbc8cc91.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/client/EgressAdapter.java:121
messageHeaderDecoder.wrap(buffer, offset);
final int templateId = messageHeaderDecoder.templateId();
final int schemaId = messageHeaderDecoder.schemaId();
if (schemaId != MessageHeaderDecoder.SCHEMA_ID)
{
if (listenerExtension != null)
{
listenerExtension.onExtensionMessage(
messageHeaderDecoder.blockLength(),
templateId,
schemaId,
messageHeaderDecoder.version(),
buffer,
offset + MessageHeaderDecoder.ENCODED_LENGTH,
length - MessageHeaderDecoder.ENCODED_LENGTH);
return;
}
throw new ClusterException("expected schemaId=" +
MessageHeaderDecoder.SCHEMA_ID + ", actual=" + schemaId);
}
switch (templateId)
{
case SessionMessageHeaderDecoder.TEMPLATE_ID:
{
sessionMessageHeaderDecoder.wrap(
buffer,
offset + MessageHeaderDecoder.ENCODED_LENGTH,
messageHeaderDecoder.blockLength(),
messageHeaderDecoder.version());
final long sessionId = sessionMessageHeaderDecoder.clusterSessionId();
if (sessionId == clusterSessionId)
{
listener.onMessage(
sessionId,View on GitHub (pinned to 6d60124e15)