openzipkin/zipkin · critical · RuntimeException

Node %s is running Cassandra %s, but minimum version is 3.11

Error message

Node %s is running Cassandra %s, but minimum version is 3.11.3

What it means

ensureVersion throws when any node in the cluster runs a Cassandra older than 3.11.3, the minimum Zipkin supports. The message names the offending node UUID and its version. Older servers lack features/behavior the schema and queries rely on, so Zipkin refuses to proceed rather than corrupt data.

Source

Thrown at zipkin-storage/cassandra/src/main/java/zipkin2/storage/cassandra/Schema.java:140

  static KeyspaceMetadata ensureKeyspaceMetadata(CqlSession session, String keyspace) {
    KeyspaceMetadata keyspaceMetadata = session.getMetadata().getKeyspace(keyspace).orElse(null);
    if (keyspaceMetadata == null) {
      throw new IllegalStateException(
        
          "Cannot read keyspace metadata for keyspace: %s and cluster: %s".formatted(
          keyspace, session.getMetadata().getClusterName()));
    }
    return keyspaceMetadata;
  }

  static Version ensureVersion(com.datastax.oss.driver.api.core.metadata.Metadata metadata) {
    Version version = null;
    for (Map.Entry<UUID, Node> entry : metadata.getNodes().entrySet()) {
      version = entry.getValue().getCassandraVersion();
      if (version == null) throw new RuntimeException("node had no version: " + entry.getValue());
      if (Version.parse("3.11.3").compareTo(version) > 0) {
        throw new RuntimeException(
          "Node %s is running Cassandra %s, but minimum version is 3.11.3".formatted(
          entry.getKey(), entry.getValue().getCassandraVersion()));
      }
    }
    if (version == null) throw new RuntimeException("No nodes in the cluster");
    LOG.info("Detected Cassandra version {}", version);
    return version;
  }

  static void ensureExists(CqlSession session, String keyspace, boolean searchEnabled) {
    KeyspaceMetadata result = session.getMetadata().getKeyspace(keyspace).orElse(null);
    Version version = ensureVersion(session.getMetadata());
    if (result == null || result.getTable(Schema.TABLE_SPAN).isEmpty()) {
      LOG.info("Installing schema {} for keyspace {}", SCHEMA_RESOURCE, keyspace);
      applyCqlFile(version, keyspace, session, SCHEMA_RESOURCE);
      if (searchEnabled) {
        LOG.info("Installing indexes {} for keyspace {}", INDEX_RESOURCE, keyspace);
        applyCqlFile(version, keyspace, session, INDEX_RESOURCE);

View on GitHub (pinned to 878ce2a1fa)

Solutions

  1. Upgrade every node in the cluster to Cassandra 3.11.3 or newer (ideally a recent 3.11.x or 4.x).
  2. Verify no stale/decommissioned nodes linger in cluster metadata; force a driver metadata refresh or restart the client.
  3. Pin dev/test environments to a supported image (e.g. cassandra:3.11.16 or 4.x).

Example fix

# before
docker run cassandra:3.0

# after
docker run cassandra:4.1
Defensive patterns

Strategy: validation

Validate before calling

for (Node n : session.getMetadata().getNodes().values()) {
  if (n.getCassandraVersion() != null && Version.parse("3.11.3").compareTo(n.getCassandraVersion()) > 0)
    throw new IllegalStateException("Node below minimum Cassandra 3.11.3: " + n);
}

Try / catch

catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().contains("minimum version")) failDeploymentWithUpgradeTask(); else throw e; }

Prevention

When it happens

Trigger: Schema ensure/validate against a mixed or legacy cluster where at least one node reports < 3.11.3 (e.g. 3.11.2, 2.x).

Common situations: Long-lived clusters never upgraded; rolling upgrades where one replica node is still old; local dev with an ancient Cassandra container image.

Related errors


AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14). Data as JSON: /api/errors/0f9e3f957873aa3e. Report an issue: GitHub.