apache/cassandra · error · IllegalArgumentException

Keyspace is already added to fetch map

Error message

Keyspace is already added to fetch map

What it means

RangeStreamer.addKeyspaceToFetch() registers the computed per-keyspace fetch work map exactly once during bootstrap/rebuild streaming. If a keyspace is already present in the toFetch map, it throws IllegalArgumentException to prevent duplicate/conflicting streaming plans for the same keyspace.

Source

Thrown at src/java/org/apache/cassandra/dht/RangeStreamer.java:409

        Multimap<InetAddressAndPort, FetchReplica> workMap;
        //Only use the optimized strategy if we don't care about strict sources, have a replication factor > 1, and no
        //transient replicas or it is intentionally skipped.
        if (CassandraRelevantProperties.SKIP_OPTIMAL_STREAMING_CANDIDATES_CALCULATION.getBoolean() ||
            useStrictSource ||
            strat == null ||
            strat.getReplicationFactor().allReplicas == 1 ||
            strat.getReplicationFactor().hasTransientReplicas())
        {
            workMap = convertPreferredEndpointsToWorkMap(fetchMap);
        }
        else
        {
            workMap = getOptimizedWorkMap(fetchMap, sourceFilters, keyspaceName, metadata.locator);
        }

        if (toFetch.put(keyspaceName, workMap) != null)
            throw new IllegalArgumentException("Keyspace is already added to fetch map");

        if (logger.isTraceEnabled())
        {
            for (Map.Entry<InetAddressAndPort, Collection<FetchReplica>> entry : workMap.asMap().entrySet())
            {
                for (FetchReplica r : entry.getValue())
                    logger.trace("{}: range source {} local range {} for keyspace {}", description, r.remote, r.local, keyspaceName);
            }
        }
    }

    /**
     * @param strat AbstractReplicationStrategy of keyspace to check
     * @return true when the node is bootstrapping, useStrictConsistency is true and # of nodes in the cluster is more than # of replica
     */
    private boolean useStrictSourcesForRanges(ReplicationParams params, AbstractReplicationStrategy strat)
    {
        return useStrictSourcesForRanges(params, strat, metadata, useStrictConsistency, movements, strictMovements);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Ensure only one bootstrap/rebuild invocation runs at a time for a node (serialize operational scripts)
  2. If retrying after a failure, recreate/restart the streaming operation rather than re-adding keyspaces to the same RangeStreamer instance
  3. Check logs / system.batches (or the failed streaming state) to confirm whether streaming already started for that keyspace before re-running

Example fix

// before
streamer.addKeyspaceToFetch(ranges, keyspace, useStrict);
streamer.addKeyspaceToFetch(ranges, keyspace, useStrict); // throws
// after
if (!alreadyFetched.contains(keyspace))
    streamer.addKeyspaceToFetch(ranges, keyspace, useStrict);
Defensive patterns

Strategy: try-catch

Validate before calling

if (toFetch.containsKey(keyspaceName)) throw new IllegalStateException(keyspaceName + " already queued for streaming");

Try / catch

try { streamer.addKeyspaceToFetch(ranges, keyspace, useStrict); } catch (IllegalArgumentException e) { if (e.getMessage().contains("already added to fetch map")) { log.warn("Skipping duplicate keyspace {}", keyspace); } else throw e; }

Prevention

When it happens

Trigger: Calling addKeyspaceToFetch twice with the same keyspaceName — e.g. bootstrap or rebuild invoked concurrently or re-entered for the same keyspace without resetting the RangeStreamer.

Common situations: Concurrent or double-invoked bootstrap/rebuild scripts (nodetool bootstrap/rebuild run twice); operational tooling retrying a failed call without recreating the RangeStreamer; test harnesses reusing the streamer across keyspaces with duplicate names.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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