aeron-io/aeron · error · ArchiveException
expected schemaId=
Error message
expected schemaId=
What it means
RecordingEventsPoller.onFragment wraps each fragment's header with MessageHeaderDecoder and requires schemaId == MessageHeaderDecoder.SCHEMA_ID. Any other schemaId means the poller received data that is not an archive recording-event message, so it throws ArchiveException('expected schemaId=..., actual=...') instead of misinterpreting the payload.
Solutions
- Ensure the poller subscribes to the correct recording events channel and streamId.
- Match Aeron Archive client and archive agent versions (identical SBE schema).
- Remove or relocate any other publishers writing to that stream.
Example fix
// before
final RecordingEventsPoller poller = new RecordingEventsPoller(
ctx.aeron().addSubscription("aeron:udp?endpoint=localhost:9999", 1), // wrong stream
listener);
// after
final RecordingEventsPoller poller = new RecordingEventsPoller(
ctx.aeron().addSubscription(eventsChannelUri, recordingEventsStreamId),
listener); Defensive patterns
Strategy: try-catch
Try / catch
try {
while (recordingEventsPoller.poll() == 0 && !isDone()) {
idleStrategy.idle();
}
} catch (ArchiveException e) {
if (e.getMessage().startsWith("expected schemaId=")) {
// stop polling, verify events channel/streamId and versions
}
} Prevention
- Verify the events subscription's channel and streamId against the archive driver configuration at startup.
- Run a version handshake (ping the archive) before relying on event polling.
When it happens
Trigger: Fragment delivered to the poller's subscription whose SBE header schemaId differs from the archive protocol schema — wrong subscription channel/stream, non-archive publisher on the stream, or archive/client built from different schema versions.
Common situations: Sharing the recording events stream with other traffic; version mismatch between the embedded archive client and the archive media driver after dependency upgrade; pointing the poller at a control response channel by mistake.
Related errors
- expected schemaId=
- expected schemaId=
- expected schemaId=
- expected schemaId=
- expected schemaId=" + MessageHeaderDecoder.SCHEMA_ID + "…
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/b48cf4c2781509d8.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-archive/src/main/java/io/aeron/archive/client/RecordingEventsPoller.java:150
/**
* {@inheritDoc}
*/
@Override
public ControlledFragmentHandler.Action onFragment(
final DirectBuffer buffer, final int offset, final int length, final Header header)
{
if (isPollComplete)
{
return ControlledFragmentHandler.Action.ABORT;
}
messageHeaderDecoder.wrap(buffer, offset);
final int schemaId = messageHeaderDecoder.schemaId();
if (schemaId != MessageHeaderDecoder.SCHEMA_ID)
{
throw new ArchiveException("expected schemaId=" + MessageHeaderDecoder.SCHEMA_ID + ", actual=" + schemaId);
}
templateId = messageHeaderDecoder.templateId();
switch (templateId)
{
case RecordingStartedDecoder.TEMPLATE_ID:
recordingStartedDecoder.wrap(
buffer,
offset + MessageHeaderDecoder.ENCODED_LENGTH,
messageHeaderDecoder.blockLength(),
messageHeaderDecoder.version());
recordingId = recordingStartedDecoder.recordingId();
recordingStartPosition = recordingStartedDecoder.startPosition();
recordingPosition = recordingStartPosition;
recordingStopPosition = Aeron.NULL_VALUE;
isPollComplete = true;
return ControlledFragmentHandler.Action.BREAK;View on GitHub (pinned to 6d60124e15)