{"record":{"id":"f47a908164365392","repo":"openzipkin/zipkin","slug":"schema-not-installed-apply-s-or-set-cassandra-e","errorCode":null,"errorMessage":"schema not installed: apply %s, or set CASSANDRA_ENSURE_SCHEMA=true","messagePattern":"schema not installed: apply (.+?), or set CASSANDRA_ENSURE_SCHEMA=true","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"zipkin-storage/cassandra/src/main/java/zipkin2/storage/cassandra/Schema.java","lineNumber":96,"sourceCode":"        \"schema lacks autocomplete indexing: apply {}, or set CASSANDRA_ENSURE_SCHEMA=true\",\n        UPGRADE_1);\n    }\n\n    if (!hasRemoteService) {\n      LOG.warn(\n        \"schema lacks remote service indexing: apply {}, or set CASSANDRA_ENSURE_SCHEMA=true\",\n        UPGRADE_2);\n    }\n\n    return md;\n  }\n\n  static void logAndThrow(String messageFormat, Object... args) {\n    String message = messageFormat.formatted(args);\n    // Ensure we can look at logs to see the problem. Otherwise, it may only\n    // be visible in API error responses, such as /health or /api/v2/traces.\n    LOG.error(message);\n    throw new RuntimeException(message);\n  }\n\n  static void initializeUDTs(CqlSession session, String keyspace) {\n    KeyspaceMetadata ks = session.getMetadata().getKeyspace(keyspace).get();\n    MutableCodecRegistry codecRegistry =\n      (MutableCodecRegistry) session.getContext().getCodecRegistry();\n\n    TypeCodec<UdtValue> annotationUDTCodec =\n      codecRegistry.codecFor(ks.getUserDefinedType(\"annotation\").get());\n    codecRegistry.register(new AnnotationCodec(annotationUDTCodec));\n\n    LOG.debug(\"Registering endpoint and annotation UDTs to keyspace {}\", keyspace);\n    TypeCodec<UdtValue> endpointUDTCodec =\n      codecRegistry.codecFor(ks.getUserDefinedType(\"endpoint\").get());\n    codecRegistry.register(new EndpointCodec(endpointUDTCodec));\n  }\n\n  static final class Metadata {","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin-storage/cassandra/src/main/java/zipkin2/storage/cassandra/Schema.java#L78-L114","documentation":"Schema.validate/logAndThrow throws a RuntimeException with 'schema not installed: apply %s, or set CASSANDRA_ENSURE_SCHEMA=true' when the expected Zipkin tables are absent from the configured keyspace. It is logged at ERROR first so the cause is visible in server logs, then rethrown so API endpoints like /health surface it.","triggerScenarios":"Building CassandraStorage with ensureSchema=false (the default validates) against a keyspace that has no Zipkin schema; pointing at the wrong keyspace or a fresh cluster that was never initialized.","commonSituations":"Operators that pre-provision schema with the shipped cql files and set CASSANDRA_ENSURE_SCHEMA=false, but apply them to a different keyspace than CASSANDRA_KEYSPACE; new environments cloned without the schema migration step.","solutions":["Set CASSANDRA_ENSURE_SCHEMA=true (or .ensureSchema(true) in the builder) once so Schema.ensure installs the schema.","Or manually apply the schema resource (zipkin2/schema/cql/*.cql) to the exact keyspace named by CASSANDRA_KEYSPACE.","Verify you are connecting to the intended cluster and keyspace (contact points, DC, keyspace name)."],"exampleFix":"// before\nCassandraStorage.newBuilder().keyspace(\"zipkin3\").ensureSchema(false).build();\n\n// after\nCassandraStorage.newBuilder().keyspace(\"zipkin3\").ensureSchema(true).build();","handlingStrategy":"validation","validationCode":"// Before enabling ensureSchema=false, confirm the schema exists\nKeyspaceMetadata ks = session.getMetadata().getKeyspace(keyspace).orElseThrow();\nif (ks.getTable(\"span\").isEmpty()) throw new IllegalStateException(\"Install zipkin schema first\");","typeGuard":null,"tryCatchPattern":"catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().contains(\"schema not installed\")) applySchema(); else throw e; }","preventionTips":["Run schema provisioning as an explicit deploy step, then validate with a /health check.","Keep CASSANDRA_KEYSPACE identical between the provisioning job and the server."],"tags":["cassandra","zipkin","schema","startup","configuration"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}