aeron-io/aeron · error · ClusterException

expected schemaId=<MessageHeaderDecoder.SCHEMA_ID>, actual=

Error message

expected schemaId=<MessageHeaderDecoder.SCHEMA_ID>, actual=<schemaId>

What it means

ControlledEgressAdapter.onFragment decoded the SBE MessageHeader of an egress fragment and found a schemaId that does not match the cluster egress schema (MessageHeaderDecoder.SCHEMA_ID). The library throws ClusterException because it cannot safely decode the message body with the compiled codecs.

Solutions

  1. Ensure client and cluster use the same aeron-cluster version so SBE schema IDs match
  2. Verify the subscription is bound to the cluster's egress channel/stream, not an unrelated stream
  3. Regenerate SBE codecs from the matching aeron-cluster-schema.xml if schemas were customized
  4. Log the actual schemaId to identify which schema produced the fragment

Example fix

// before: mixed versions
// client: aeron-cluster 1.40.0, cluster: 1.44.0
// after: align versions
// client and cluster both on aeron-cluster 1.44.0
Defensive patterns

Strategy: validation

Validate before calling

// Check header schemaId before offering fragment to the adapter
MessageHeaderDecoder h = new MessageHeaderDecoder().wrap(buffer, offset);
if (h.schemaId() != MessageHeaderDecoder.SCHEMA_ID) {
    // skip/log instead of calling adapter
}

Try / catch

try {
    adapter.onFragment(buffer, offset, length, header);
} catch (ClusterException ex) {
    // log schema mismatch, investigate version skew
}

Prevention

When it happens

Trigger: Feeding the adapter a fragment from a stream carrying a different SBE schema (wrong stream/subscription wiring); cluster and client built against different aeron-cluster versions with mismatched schema IDs.

Common situations: Client pointing at the wrong image/publication; mixed Aeron versions between cluster and client after an upgrade; custom messages published onto the egress channel.

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


AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12). Data as JSON: /api/errors/84b54f7e28a4d33c. Report an issue: GitHub.

Appendix: source

Thrown at aeron-cluster/src/main/java/io/aeron/cluster/client/ControlledEgressAdapter.java:122

    {
        messageHeaderDecoder.wrap(buffer, offset);

        final int templateId = messageHeaderDecoder.templateId();
        final int schemaId = messageHeaderDecoder.schemaId();
        if (schemaId != MessageHeaderDecoder.SCHEMA_ID)
        {
            if (listenerExtension != null)
            {
                return listenerExtension.onExtensionMessage(
                    messageHeaderDecoder.blockLength(),
                    templateId,
                    schemaId,
                    messageHeaderDecoder.version(),
                    buffer,
                    offset + MessageHeaderDecoder.ENCODED_LENGTH,
                    length - MessageHeaderDecoder.ENCODED_LENGTH);
            }
            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)
                {
                    return listener.onMessage(
                        sessionId,

View on GitHub (pinned to 6d60124e15)