{"record":{"id":"07eda86d296c41d2","repo":"aeron-io/aeron","slug":"expected-schemaid-messageheaderdecoder-schema-id-actual-07eda8","errorCode":null,"errorMessage":"expected schemaId=${MessageHeaderDecoder.SCHEMA_ID}, actual=${schemaId}","messagePattern":"expected schemaId=(.+?), actual=(.+?)","errorType":"exception","errorClass":"ClusterException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/ConsensusAdapter.java","lineNumber":87,"sourceCode":"    public int poll()\n    {\n        return subscription.poll(fragmentAssembler, FRAGMENT_LIMIT);\n    }\n\n    public int poll(final int limit)\n    {\n        return subscription.poll(fragmentAssembler, limit);\n    }\n\n    @SuppressWarnings(\"MethodLength\")\n    public void onFragment(final DirectBuffer buffer, final int offset, final int length, final Header header)\n    {\n        messageHeaderDecoder.wrap(buffer, offset);\n\n        final int schemaId = messageHeaderDecoder.schemaId();\n        if (schemaId != MessageHeaderDecoder.SCHEMA_ID)\n        {\n            throw new ClusterException(\"expected schemaId=\" + MessageHeaderDecoder.SCHEMA_ID + \", actual=\" + schemaId);\n        }\n\n        switch (messageHeaderDecoder.templateId())\n        {\n            case CanvassPositionDecoder.TEMPLATE_ID:\n                canvassPositionDecoder.wrap(\n                    buffer,\n                    offset + MessageHeaderDecoder.ENCODED_LENGTH,\n                    messageHeaderDecoder.blockLength(),\n                    messageHeaderDecoder.version());\n\n                consensusModuleAgent.onCanvassPosition(\n                    canvassPositionDecoder.logLeadershipTermId(),\n                    canvassPositionDecoder.logPosition(),\n                    canvassPositionDecoder.leadershipTermId(),\n                    canvassPositionDecoder.followerMemberId(),\n                    canvassPositionDecoder.protocolVersion());\n                break;","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/ConsensusAdapter.java#L69-L105","documentation":"ConsensusAdapter.onFragment wraps each incoming buffer with MessageHeaderDecoder and verifies the SBE block schemaId matches the cluster protocol's expected SCHEMA_ID; a mismatch throws ClusterException. This means a message arrived on the consensus transport that is not a valid cluster-protocol SBE message.","triggerScenarios":"Receiving a fragment on the cluster consensus channel whose SBE header schemaId differs from MessageHeaderDecoder.SCHEMA_ID (e.g. messages from another Aeron/SBE protocol version or a different application sharing the channel/stream).","commonSituations":"Two Aeron versions or applications configured to use the same channel/stream: one speaks a different SBE schema; misconfigured consensus channel overlapping with another cluster's streamId; corrupted messages from a misbehaving publisher.","solutions":["Verify all cluster members run the same Aeron version so their SBE schemas match.","Check aeron.cluster.channels / consensus channel and streamId configuration for collisions with other applications.","Ensure no other publisher is sending on the consensus channel/streamId.","If connecting clusters together, use distinct channels or an egress/ingest boundary rather than sharing the consensus stream."],"exampleFix":"// before\n// node A: -Daeron.cluster.consensus.channel=aeron:udp?endpoint=host:9010 (shared with another app sending SBE with different schema)\n// after: dedicate the stream/channel to the cluster\n-Daeron.cluster.consensus.channel=aeron:udp?endpoint=host:9020\n-Daeron.cluster.consensus.streamId=101","handlingStrategy":"validation","validationCode":"// before joining a cluster, verify config consistency\nif (!consensusChannel.equals(expectedConsensusChannel) || consensusStreamId != expectedStreamId)\n{\n    throw new IllegalStateException(\"consensus channel/streamId mismatch with cluster config\");\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    consensusModule.start();\n}\ncatch (ClusterException ex)\n{\n    if (ex.getMessage().contains(\"expected schemaId\"))\n    {\n        // wrong sender or Aeron version on the consensus channel\n    }\n    else throw ex;\n}","preventionTips":["Pin the same Aeron version on all cluster members.","Never share the consensus channel/streamId with other applications or clusters.","Audit publishers on the consensus endpoint if the error appears intermittently."],"tags":["aeron","cluster","sbe","protocol"],"backgroundTag":"schema-validation-failed","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}