{"record":{"id":"98e9fb51daebe4a8","repo":"aeron-io/aeron","slug":"expected-schemaid","errorCode":null,"errorMessage":"expected schemaId=","messagePattern":"expected schemaId=","errorType":"exception","errorClass":"ArchiveException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/client/AsyncAeronArchive.java","lineNumber":295,"sourceCode":"        {\n            state = State.CLOSED;\n\n            CloseHelper.quietCloseAll(asyncConnect, aeronArchive);\n        }\n    }\n\n    private ControlledFragmentHandler.Action onFragment(\n        final DirectBuffer buffer,\n        final int offset,\n        final int length,\n        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 ArchiveException(\"expected schemaId=\" + MessageHeaderDecoder.SCHEMA_ID + \", actual=\" + schemaId);\n        }\n\n        final int templateId = messageHeaderDecoder.templateId();\n        switch (templateId)\n        {\n            case ControlResponseDecoder.TEMPLATE_ID:\n                controlResponseDecoder.wrap(\n                    buffer,\n                    offset + MessageHeaderEncoder.ENCODED_LENGTH,\n                    messageHeaderDecoder.blockLength(),\n                    messageHeaderDecoder.version());\n\n                if (controlResponseDecoder.controlSessionId() == controlSessionId)\n                {\n                    listener.onControlResponse(\n                        controlResponseDecoder.correlationId(),\n                        controlResponseDecoder.relevantId(),\n                        controlResponseDecoder.code(),","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/client/AsyncAeronArchive.java#L277-L313","documentation":"AsyncAeronArchive.ControlResponseFragmentHandler.onFragment wraps the incoming buffer with the SBE MessageHeaderDecoder and throws ArchiveException when the decoded schemaId does not match the archive control-protocol schema id. The fragment on the control-response channel is not a valid archive control message, so it cannot be safely decoded.","triggerScenarios":"onFragment receives a buffer whose MessageHeaderDecoder.schemaId() differs from MessageHeaderDecoder.SCHEMA_ID — e.g. a foreign SBE-encoded message published onto the control-response stream, a mismatched archive client/server protocol version, or corrupted/interleaved traffic on the control channel.","commonSituations":"Pointing a client built against one aeron-archive version at an archive running a different SBE schema; another application publishing onto the same control-response stream/channel; stale jar mixing after an upgrade.","solutions":["Align the aeron-archive client and archive server versions so both use the same SBE schema id","Ensure only the archive publishes on the control-response channel/stream you subscribed to","Verify channel/stream configuration: the control response subscription should not carry unrelated traffic","Clean build to avoid stale generated SBE codecs from a different schema version on the classpath"],"exampleFix":"// before\nAeronArchive.connect(new AeronArchive.Context().controlResponseChannel(\"aeron:udp?endpoint=localhost:8010\"));\n// ...server on a different protocol version\n\n// after\n// pin matching versions\ndependencies {\n    implementation(\"io.aeron:aeron-archive:1.44.1\") // same as archive server\n}","handlingStrategy":"validation","validationCode":"MessageHeaderDecoder h = new MessageHeaderDecoder().wrap(buffer, offset);\nif (h.schemaId() != MessageHeaderDecoder.SCHEMA_ID) {\n    throw new IllegalStateException(\"foreign message on control stream, schemaId=\" + h.schemaId());\n}","typeGuard":"boolean isArchiveControlSchema(DirectBuffer buf, int offset) {\n    return new MessageHeaderDecoder().wrap(buf, offset).schemaId() == MessageHeaderDecoder.SCHEMA_ID;\n}","tryCatchPattern":"try {\n    asyncArchive.pollResponses();\n} catch (ArchiveException e) {\n    if (e.getMessage().startsWith(\"expected schemaId=\")) {\n        log.warn(\"non-archive traffic on control stream; check versions/publishers\", e);\n    }\n}","preventionTips":["Pin identical aeron-archive versions on client and server","Never publish application messages on the archive control-response stream","Clean builds to avoid stale generated SBE codecs on the classpath","Log schemaId/templateId of unexpected fragments to identify the foreign source"],"tags":["sbe","schema","protocol-mismatch","aeron-archive"],"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"}