apache/cassandra · warning

Picking random token for a single vnode. You should probabl

Error message

Picking random token for a single vnode.  You should probably add more vnodes and/or use the automatic token allocation mechanism.

What it means

BootStrapper.getBootstrapTokens falls back to random token generation when no explicit allocation mechanism applies. With numTokens == 1 the random choice yields poor, unpredictable load distribution, so it logs this warning and proceeds. It is a configuration-guidance warning, not a failure.

Source

Thrown at src/java/org/apache/cassandra/dht/BootStrapper.java:248

        if (initialTokens.size() > 0)
        {
            Collection<Token> tokens = getSpecifiedTokens(metadata, initialTokens);
            BootstrapDiagnostics.useSpecifiedTokens(address, allocationKeyspace, tokens, DatabaseDescriptor.getNumTokens());
            return tokens;
        }

        int numTokens = DatabaseDescriptor.getNumTokens();
        if (numTokens < 1)
            throw new ConfigurationException("num_tokens must be >= 1");

        if (allocationKeyspace != null)
            return allocateTokens(metadata, address, allocationKeyspace, numTokens);

        if (allocationLocalRf != null)
            return allocateTokens(metadata, address, allocationLocalRf, numTokens);

        if (numTokens == 1)
            logger.warn("Picking random token for a single vnode.  You should probably add more vnodes and/or use the automatic token allocation mechanism.");

        Collection<Token> tokens = getRandomTokens(metadata, numTokens);
        BootstrapDiagnostics.useRandomTokens(address, metadata, numTokens, tokens);
        return tokens;
    }

    private static Collection<Token> getSpecifiedTokens(final ClusterMetadata metadata,
                                                        Collection<String> initialTokens)
    {
        logger.info("tokens manually specified as {}",  initialTokens);
        List<Token> tokens = new ArrayList<>(initialTokens.size());
        for (String tokenString : initialTokens)
        {
            Token token = metadata.tokenMap.partitioner().getTokenFactory().fromString(tokenString);
            if (metadata.tokenMap.owner(token) != null)
                throw new ConfigurationException("Bootstrapping to existing token " + tokenString + " is not allowed (decommission/removenode the old node first).");
            tokens.add(token);
        }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Set num_tokens to a higher value (e.g. 16) in cassandra.yaml before bootstrap.
  2. Configure allocate_tokens_for_keyspace / allocation_keyspace to use the automatic token allocation mechanism.
  3. Set allocate_tokens_for_local_replication_factor for local-RF-aware allocation.
  4. If random tokens are truly intended, ignore the warning; the bootstrap proceeds.

Example fix

# before (cassandra.yaml)
num_tokens: 1

# after
num_tokens: 16
# or
allocate_tokens_for_keyspace: my_keyspace
Defensive patterns

Strategy: validation

Validate before calling

# fail early on poor token config before bootstrap
grep -E '^num_tokens:' conf/cassandra.yaml  # require num_tokens > 1 or allocation settings present

Prevention

When it happens

Trigger: Bootstrapping a node with num_tokens=1 and neither allocation_keyspace (allocateTokens) nor allocate_tokens_for_local_replication_factor configured, so getRandomTokens is used.

Common situations: Legacy single-token-per-node configs carried into new deployments; operators unaware of the automatic token allocation options; test/single-node clusters using default-random tokens.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/79bd7b5daef9fd2a. Report an issue: GitHub.