openzipkin/zipkin · error · RuntimeException

node had no version: %s

Error message

node had no version: %s

What it means

ensureVersion throws RuntimeException('node had no version: %s') when a node in cluster metadata reports a null Cassandra version. The driver could not determine the server version for that node, which makes Zipkin's version-dependent schema logic (e.g. reviseCQL for Cassandra 4) impossible to apply safely.

Source

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

    }
  }

  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) {

View on GitHub (pinned to 878ce2a1fa)

Solutions

  1. Retry after cluster metadata settles (nodes finish joining and report versions).
  2. Upgrade the Cassandra driver / server combination to a supported pair (Cassandra >= 3.11.3).
  3. If a proxy sits in front of Cassandra, bypass it for Zipkin's connections.
Defensive patterns

Strategy: retry

Validate before calling

boolean allVersioned = session.getMetadata().getNodes().values().stream().allMatch(n -> n.getCassandraVersion() != null);
if (!allVersioned) throw new IllegalStateException("Cluster metadata incomplete; retry after nodes settle");

Try / catch

catch (RuntimeException e) { if (e.getMessage() != null && e.getMessage().startsWith("node had no version")) retryWithBackoff(); else throw e; }

Prevention

When it happens

Trigger: Schema ensure/validate iterating cluster nodes where getCassandraVersion() returns null — common right after a node joins or during metadata refresh, or with proxies/mediators that do not advertise a Cassandra version.

Common situations: Connecting through a driver-incompatible intermediary; a node still initializing; driver metadata not yet refreshed; very old or forked Cassandra-compatible servers.

Related errors


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