{"record":{"id":"1dd736b62723f2e8","repo":"aeron-io/aeron","slug":"expected-schemaid-messageheaderdecoder-schema-id-actual-1dd736","errorCode":null,"errorMessage":"expected schemaId=${MessageHeaderDecoder.SCHEMA_ID}, actual=${schemaId}","messagePattern":"expected schemaId=(.+?), actual=(.+?)","errorType":"console","errorClass":"ClusterException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/service/ServiceAdapter.java","lineNumber":63,"sourceCode":"\n    public void close()\n    {\n        CloseHelper.close(subscription);\n    }\n\n    int poll()\n    {\n        return subscription.poll(fragmentAssembler, FRAGMENT_LIMIT);\n    }\n\n    private 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 JoinLogDecoder.TEMPLATE_ID:\n                joinLogDecoder.wrap(\n                    buffer,\n                    offset + MessageHeaderDecoder.ENCODED_LENGTH,\n                    messageHeaderDecoder.blockLength(),\n                    messageHeaderDecoder.version());\n\n                clusteredServiceAgent.onJoinLog(\n                    joinLogDecoder.logPosition(),\n                    joinLogDecoder.maxLogPosition(),\n                    joinLogDecoder.memberId(),\n                    joinLogDecoder.logSessionId(),\n                    joinLogDecoder.logStreamId(),\n                    joinLogDecoder.isStartup() == BooleanType.TRUE,","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/service/ServiceAdapter.java#L45-L81","documentation":"ServiceAdapter.onFragment decodes each incoming SBE message beginning with a MessageHeaderDecoder and validates the schemaId against the cluster protocol schema. A mismatch means the fragment is not encoded with the expected cluster-service protocol schema, so it throws this ClusterException rather than misinterpreting the buffer.","triggerScenarios":"A fragment published on the service adapter's (consensus module -> service) stream whose SBE header schemaId differs from cluster-cluster MessageHeaderDecoder.SCHEMA_ID — e.g. foreign/corrupt data on the channel or a version-incompatible sender.","commonSituations":"Mixed Aeron versions in one cluster (different generated schema ids); custom protocol extensions sending on the wrong stream; replay/corrupt log data fed to the adapter; connecting a service to the wrong channel/stream-id.","solutions":["Run matching Aeron/artifact versions across all cluster nodes (all nodes built from the same aeron-cluster version).","Verify the service is subscribed on the correct consensus module stream and streamId.","Check for corruption or stale data in the cluster/mark file and log directories; clean and re-form the cluster.","Confirm no custom publisher is writing non-cluster messages to this image."],"exampleFix":"// before\n// service built against io.aeron:aeron-cluster:1.40 mixing with 1.44 nodes\n// after\n// align all nodes to the same version, e.g.:\n// implementation 'io.aeron:aeron-cluster:1.44.1' in every module","handlingStrategy":"validation","validationCode":"// before subscribing/decoding, verify sender version compatibility:\n// ensure all nodes use the same aeron-cluster artifact version generating the SBE schema","typeGuard":null,"tryCatchPattern":"try {\n    serviceAdapter.onFragment(buffer, offset, length, header);\n} catch (ClusterException e) {\n    if (e.getMessage().contains(\"expected schemaId=\")) {\n        // halt and alert: protocol/version mismatch in cluster\n    } else {\n        throw e;\n    }\n}","preventionTips":["Pin identical Aeron versions across all cluster nodes.","Never publish non-cluster SBE messages on the consensus-module-to-service stream.","Clean stale cluster/log directories after failed runs or upgrades."],"tags":["aeron","sbe","schema","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"}