{"record":{"id":"40750cf9ad8a840b","repo":"apache/cassandra","slug":"coordinator-schema-for-s-s-with-epoch-s-is-behi","errorCode":null,"errorMessage":"Coordinator schema for %s.%s with epoch %s is behind our schema %s","messagePattern":"Coordinator schema for (.+?)\\.(.+?) with epoch (.+?) is behind our schema (.+?)","errorType":"exception","errorClass":"CoordinatorBehindException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/ReadCommandVerbHandler.java","lineNumber":157,"sourceCode":"    {\n        ReadCommand readCommand = message.payload;\n\n        if (SchemaConstants.isSystemKeyspace(readCommand.metadata().keyspace) ||\n            readCommand.serializedAtEpoch() == null) // don't try to catch up with pre-5.0 nodes\n            return metadata;\n\n        Keyspace ks = metadata.schema.getKeyspace(readCommand.metadata().keyspace);\n        ColumnFamilyStore cfs = ks != null ? ks.getColumnFamilyStore(readCommand.metadata().id) : null;\n        Epoch localComparisonEpoch = metadata.epoch;\n        if (cfs != null)\n            localComparisonEpoch = cfs.metadata().epoch;\n\n        if (localComparisonEpoch.isBefore(readCommand.serializedAtEpoch()))\n            metadata = ClusterMetadataService.instance().fetchLogFromPeerOrCMS(metadata, message.from(), message.epoch());\n        else if (localComparisonEpoch.isAfter(readCommand.serializedAtEpoch()))\n        {\n            TCMMetrics.instance.coordinatorBehindSchema.mark();\n            throw new CoordinatorBehindException(String.format(\"Coordinator schema for %s.%s with epoch %s is behind our schema %s\",\n                                                               message.payload.metadata().keyspace,\n                                                               message.payload.metadata().name,\n                                                               readCommand.serializedAtEpoch(),\n                                                               localComparisonEpoch));\n        }\n        ks = metadata.schema.getKeyspace(readCommand.metadata().keyspace);\n        if (ks == null || ks.getColumnFamilyStore(readCommand.metadata().id) == null)\n            throw new IllegalStateException(\"Unknown table \" + readCommand.metadata().id +\" after fetching remote log entries\");\n        return metadata;\n    }\n\n    private ClusterMetadata checkTokenOwnership(ClusterMetadata metadata, Message<ReadCommand> message)\n    {\n        ReadCommand command = message.payload;\n\n        if (command.metadata().isVirtual())\n            return metadata;\n","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/ReadCommandVerbHandler.java#L139-L175","documentation":"ReadCommandVerbHandler.checkSchemaVersion rejects a read request when the replica's local schema epoch is AHEAD of the epoch the coordinator serialized the command at. The replica cannot serve data under the coordinator's older schema view, so it marks coordinatorBehindSchema and throws CoordinatorBehindException, expecting the coordinator to refresh its schema.","triggerScenarios":"A replica calls doVerb -> checkSchemaVersion; localComparisonEpoch.isAfter(readCommand.serializedAtEpoch()) and fetching the coordinator's log state from peer/CMS does not bring the coordinator up to the local epoch.","commonSituations":"Schema change (CREATE/ALTER TABLE) just committed and replicated, but the coordinator node has not yet applied the new epoch; coordinator behind on TCM log replay after a restart; mixing node versions during upgrade.","solutions":["Allow the coordinator to catch up on schema epochs (it should refetch the log and retry); verify with `nodetool describecluster` schema versions","On the coordinator, force a metadata log refresh/restart if it stays pinned at an old epoch","Check replica-to-CMS connectivity so epoch dissemination works","Ensure consistent Cassandra versions across the cluster during upgrades"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    result = session.execute(query);\n} catch (CoordinatorBehindException e) {\n    // coordinator schema older than replica; refresh session/schema metadata and retry\n    cluster.refreshSchema();\n    result = session.execute(query);\n}","preventionTips":["Wait for `nodetool describecluster` to show a single schema version after DDL before issuing reads","Avoid DDL storms immediately before read-heavy workloads","Keep TCM log dissemination healthy (CMS reachability)","Restart coordinators stuck at old epochs promptly"],"tags":["distributed-consistency","schema-epoch","tcm","coordinator-behind"],"backgroundTag":"schema-validation-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}