openzipkin/zipkin · critical · RuntimeException
schema not installed: apply %s, or set CASSANDRA_ENSURE_SCHE
Error message
schema not installed: apply %s, or set CASSANDRA_ENSURE_SCHEMA=true
What it means
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.
Source
Thrown at zipkin-storage/cassandra/src/main/java/zipkin2/storage/cassandra/Schema.java:96
"schema lacks autocomplete indexing: apply {}, or set CASSANDRA_ENSURE_SCHEMA=true",
UPGRADE_1);
}
if (!hasRemoteService) {
LOG.warn(
"schema lacks remote service indexing: apply {}, or set CASSANDRA_ENSURE_SCHEMA=true",
UPGRADE_2);
}
return md;
}
static void logAndThrow(String messageFormat, Object... args) {
String message = messageFormat.formatted(args);
// Ensure we can look at logs to see the problem. Otherwise, it may only
// be visible in API error responses, such as /health or /api/v2/traces.
LOG.error(message);
throw new RuntimeException(message);
}
static void initializeUDTs(CqlSession session, String keyspace) {
KeyspaceMetadata ks = session.getMetadata().getKeyspace(keyspace).get();
MutableCodecRegistry codecRegistry =
(MutableCodecRegistry) session.getContext().getCodecRegistry();
TypeCodec<UdtValue> annotationUDTCodec =
codecRegistry.codecFor(ks.getUserDefinedType("annotation").get());
codecRegistry.register(new AnnotationCodec(annotationUDTCodec));
LOG.debug("Registering endpoint and annotation UDTs to keyspace {}", keyspace);
TypeCodec<UdtValue> endpointUDTCodec =
codecRegistry.codecFor(ks.getUserDefinedType("endpoint").get());
codecRegistry.register(new EndpointCodec(endpointUDTCodec));
}
static final class Metadata {View on GitHub (pinned to 878ce2a1fa)
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).
Example fix
// before
CassandraStorage.newBuilder().keyspace("zipkin3").ensureSchema(false).build();
// after
CassandraStorage.newBuilder().keyspace("zipkin3").ensureSchema(true).build(); Defensive patterns
Strategy: validation
Validate before calling
// Before enabling ensureSchema=false, confirm the schema exists
KeyspaceMetadata ks = session.getMetadata().getKeyspace(keyspace).orElseThrow();
if (ks.getTable("span").isEmpty()) throw new IllegalStateException("Install zipkin schema first"); Try / catch
catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().contains("schema not installed")) applySchema(); else throw e; } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Session initialization failed. See server logs
- No valid endpoints found in ES hosts: {hosts}
- {annotationQueryString} query unsupported due to missing ann
- remoteService={remoteService} unsupported due to missing tab
- autocompleteTtl <= 0
AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14).
Data as JSON: /api/errors/f47a908164365392.
Report an issue: GitHub.