{"record":{"id":"d465fbfb06414245","repo":"spring-projects/spring-ai","slug":"waiting-for-cluster-schema-agreement-sleeping-10s","errorCode":null,"errorMessage":"Waiting for cluster schema agreement, sleeping 10s…","messagePattern":"Waiting for cluster schema agreement, sleeping 10s…","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"memory-repositories/spring-ai-model-chat-memory-repository-cassandra/src/main/java/org/springframework/ai/chat/memory/repository/cassandra/SchemaUtil.java","lineNumber":43,"sourceCode":"import org.apache.commons.logging.LogFactory;\n\n/**\n * Utility class for working with Cassandra schema.\n *\n * @author Mick Semb Wever\n * @since 1.0.0\n */\npublic final class SchemaUtil {\n\n\tprivate static final Log logger = LogFactory.getLog(SchemaUtil.class);\n\n\tprivate SchemaUtil() {\n\n\t}\n\n\tpublic static void checkSchemaAgreement(CqlSession session) throws IllegalStateException {\n\t\tif (!session.checkSchemaAgreement()) {\n\t\t\tlogger.warn(\"Waiting for cluster schema agreement, sleeping 10s…\");\n\t\t\ttry {\n\t\t\t\tThread.sleep(Duration.ofSeconds(10).toMillis());\n\t\t\t}\n\t\t\tcatch (InterruptedException ex) {\n\t\t\t\tThread.currentThread().interrupt();\n\t\t\t\tthrow new IllegalStateException(ex);\n\t\t\t}\n\t\t\tif (!session.checkSchemaAgreement()) {\n\t\t\t\tlogger.error(\"no cluster schema agreement still, continuing, let's hope this works…\");\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic static void ensureKeyspaceExists(CqlSession session, String keyspaceName) {\n\t\tif (session.getMetadata().getKeyspace(keyspaceName).isEmpty()) {\n\t\t\tSimpleStatement keyspaceStmt = SchemaBuilder.createKeyspace(keyspaceName)\n\t\t\t\t.ifNotExists()\n\t\t\t\t.withSimpleStrategy(1)","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/memory-repositories/spring-ai-model-chat-memory-repository-cassandra/src/main/java/org/springframework/ai/chat/memory/repository/cassandra/SchemaUtil.java#L25-L61","documentation":"SchemaUtil.checkSchemaAgreement() logs this warning when the Cassandra cluster has not yet reached schema agreement, then sleeps 10 seconds and re-checks. Schema agreement means all nodes have converged on the latest schema after DDL changes; proceeding early can cause inconsistent reads/writes. If still not in agreement (or interrupted) it throws IllegalStateException.","triggerScenarios":"Calling checkSchemaAgreement(session) right after creating/altering keyspace or tables (e.g. during schema initialization at startup) while one or more Cassandra nodes have not yet applied the schema change.","commonSituations":"Application startup racing schema creation on multi-node clusters; large clusters or nodes under load slowing schema propagation; running DDL migrations then immediately writing; interrupted sleep during shutdown converting to IllegalStateException.","solutions":["Just wait: the utility already sleeps 10s and re-checks; ensure your startup sequence tolerates the delay","Verify all cluster nodes are up and reachable (nodetool status); a down node blocks schema agreement","Check nodetool describecluster for schema disagreement and run a repair if nodes diverged","Run schema DDL once ahead of deployment (migration job) instead of at application startup","If you see IllegalStateException from interruption, check for shutdown hooks or timeouts interrupting the startup thread"],"exampleFix":"// before: DDL then immediate reads at boot\nschemaUtil.createKeyspace();\nSchemaUtil.checkSchemaAgreement(session);\nrepository.saveAll(...);\n\n// after: let the tool wait (it does), and fail fast on real disagreement\nSchemaUtil.checkSchemaAgreement(session); // sleeps 10s if needed\n// if it still throws, run: nodetool describecluster / nodetool repair","handlingStrategy":"retry","validationCode":"boolean inAgreement = session.checkSchemaAgreement();\nif (!inAgreement) { /* expect a 10s wait from SchemaUtil, or wait yourself before DDL-dependent work */ }","typeGuard":null,"tryCatchPattern":"try {\n    SchemaUtil.checkSchemaAgreement(session);\n} catch (IllegalStateException e) {\n    throw new IllegalStateException(\"Cassandra cluster failed to reach schema agreement; check nodetool describecluster\", e);\n}","preventionTips":["Run DDL migrations before app startup, not during it","Keep all Cassandra nodes healthy (nodetool status) to avoid blocked agreement","Allow generous startup timeouts on multi-node clusters","Avoid interrupting startup threads (shutdown hooks, aggressive health checks)"],"tags":["cassandra","schema-agreement","ddl","startup"],"backgroundTag":"schema-validation-failed","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}