aeron-io/aeron · error · ClusterException
expected schemaId= , actual=
Error message
expected schemaId=${MessageHeaderDecoder.SCHEMA_ID}, actual=${schemaId} What it means
ServiceSnapshotLoader.onFragment validates the SBE MessageHeader schemaId of every fragment received while loading a service snapshot from the archive. If the schemaId does not match the cluster protocol's MessageHeaderDecoder.SCHEMA_ID, the snapshot data is not in the expected schema and this ClusterException is thrown.
Solutions
- Restore a snapshot taken with the same Aeron/protocol version as the running code.
- Perform a supported upgrade path (replay with old version, take new snapshot) rather than replaying old snapshots on new code.
- Verify the archive replay is bound to the correct recordingId for the service snapshot.
- Check snapshot recording integrity; re-take the snapshot if data is corrupt.
Example fix
// before // replaying snapshot from aeron 1.38 with aeron-cluster 1.44 // after // upgrade cluster with old version, let it snapshot, then start new version on the new snapshot
Defensive patterns
Strategy: try-catch
Try / catch
try {
snapshotLoader.onFragment(buffer, offset, length, header);
} catch (ClusterException e) {
if (e.getMessage().contains("expected schemaId=")) {
// snapshot schema mismatch: restore compatible snapshot or upgrade via re-snapshot
} else {
throw e;
}
} Prevention
- Only replay snapshots produced by the same Aeron/protocol version.
- Follow supported upgrade procedures (old version replays, new snapshot, then upgrade).
- Validate recordingId targets the intended service snapshot before replay.
When it happens
Trigger: Replaying a snapshot recording whose fragments were written with a different SBE schema id — snapshot produced by a different Aeron version, corrupted snapshot data, or unrelated data captured in the recording.
Common situations: Upgrading Aeron versions across a cluster while replaying old snapshots; restoring a snapshot from a different cluster/backup; archive replay misconfiguration pointing the loader at the wrong recording.
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
- expected schemaId= , actual=
- expected schemaId= , actual=
- expected schemaId=<MessageHeaderDecoder.SCHEMA_ID>, actual=
- expected schemaId=<MessageHeaderDecoder.SCHEMA_ID>, actual=
- expected schemaId=<MessageHeaderDecoder.SCHEMA_ID>, actual=
AI-assisted analysis of aeron-io/aeron@6d60124e15 (2026-09-12).
Data as JSON: /api/errors/fe589c0b60d64643.
Report an issue: GitHub.
Appendix: source
Thrown at aeron-cluster/src/main/java/io/aeron/cluster/service/ServiceSnapshotLoader.java:79
TimeUnit timeUnit()
{
return timeUnit;
}
int poll()
{
return image.controlledPoll(fragmentAssembler, FRAGMENT_LIMIT);
}
public Action onFragment(final DirectBuffer buffer, final int offset, final int length, final Header header)
{
messageHeaderDecoder.wrap(buffer, offset);
final int schemaId = messageHeaderDecoder.schemaId();
if (MessageHeaderDecoder.SCHEMA_ID != schemaId)
{
throw new ClusterException("expected schemaId=" + MessageHeaderDecoder.SCHEMA_ID + ", actual=" + schemaId);
}
switch (messageHeaderDecoder.templateId())
{
case SnapshotMarkerDecoder.TEMPLATE_ID:
snapshotMarkerDecoder.wrap(
buffer,
offset + MessageHeaderDecoder.ENCODED_LENGTH,
messageHeaderDecoder.blockLength(),
messageHeaderDecoder.version());
final long typeId = snapshotMarkerDecoder.typeId();
if (SNAPSHOT_TYPE_ID != typeId)
{
throw new ClusterException("unexpected snapshot type: " + typeId);
}
switch (snapshotMarkerDecoder.mark())View on GitHub (pinned to 6d60124e15)