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
- Ensure only one bootstrap/rebuild invocation runs at a time for a node (serialize operational scripts)
- If retrying after a failure, recreate/restart the streaming operation rather than re-adding keyspaces to the same RangeStreamer instance
- 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
- Serialize bootstrap/rebuild invocations per node
- Track fetched keyspaces in a Set before calling addKeyspaceToFetch
- Recreate the RangeStreamer for retry attempts rather than reusing it
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
- Unable to find sufficient sources for streaming range " + tr
- Unable to find sufficient sources for streaming range " + ra
- Unable to find sufficient sources for streaming range in ke
- Discovered existing bootstrap data and %s is not configured;
- Could not finish join for during replacement
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/b3e7a5bca80437a9.
Report an issue: GitHub.