apache/cassandra · error · java.lang.IllegalStateException
0x0000
0x0000
Error message
Cannot rebuild index %s as another index build for the same index is currently in progress.
What it means
IllegalStateException thrown by SecondaryIndexManager.markIndexesBuilding when a full rebuild is requested for an index that already has an in-progress build (inProgressBuilds counter > 0). Prevents two concurrent builds of the same index.
Source
Thrown at src/java/org/apache/cassandra/index/SecondaryIndexManager.java:816
* @param isFullRebuild {@code true} if this method is invoked as a full index rebuild, {@code false} otherwise
* @param isNewCF {@code true} if this method is invoked when initializing a new table/columnfamily (i.e. loading a CF at startup),
* {@code false} for all other cases (i.e. newly added index)
*/
@VisibleForTesting
public synchronized void markIndexesBuilding(Set<Index> indexes, boolean isFullRebuild, boolean isNewCF)
{
String keyspaceName = baseCfs.getKeyspaceName();
// First step is to validate against concurrent rebuilds; it would be more optimized to do everything on a single
// step, but we're not really expecting a very high number of indexes, and this isn't on any hot path, so
// we're favouring readability over performance
indexes.forEach(index ->
{
String indexName = index.getIndexMetadata().name;
AtomicInteger counter = inProgressBuilds.computeIfAbsent(indexName, ignored -> new AtomicInteger(0));
if (counter.get() > 0 && isFullRebuild)
throw new IllegalStateException(String.format("Cannot rebuild index %s as another index build for the same index is currently in progress.", indexName));
});
// Second step is the actual marking:
indexes.forEach(index ->
{
String indexName = index.getIndexMetadata().name;
AtomicInteger counter = inProgressBuilds.computeIfAbsent(indexName, ignored -> new AtomicInteger(0));
if (isFullRebuild)
{
needsFullRebuild.remove(indexName);
makeIndexNonQueryable(index, Index.Status.FULL_REBUILD_STARTED);
}
if (counter.getAndIncrement() == 0 && DatabaseDescriptor.isDaemonInitialized() && !isNewCF)
SystemKeyspace.setIndexRemoved(keyspaceName, indexName);
});
}View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Wait for the current build to finish (check system.built / in-progress tasks, `nodetool compactionstats`) before rebuilding
- If the first build is genuinely stuck, restart the node to clear in-progress state, then rebuild
- Serialize rebuild operations in automation; do not retry in a tight loop
- Use `nodetool indexbuilds`/logs to confirm the prior build completed
Example fix
// before
cfim.rebuildIndexesBlocking(Set.of("idx")); // while already building
// after
if (!isIndexBuilding("idx")) {
cfim.rebuildIndexesBlocking(Set.of("idx"));
} else {
logger.info("Index idx still building; skipping rebuild");
} Defensive patterns
Strategy: validation
Validate before calling
// check for an in-progress build before requesting a rebuild
if (!indexBuildsComplete(keyspace, table, indexName)) {
logger.info("Index {} still building; rebuild skipped", indexName);
return;
} Try / catch
try {
indexManager.rebuildIndexesBlocking(indexes);
} catch (IllegalStateException e) {
if (e.getMessage().contains("currently in progress"))
logger.info("Rebuild skipped: build already running");
else throw e;
} Prevention
- Wait for build completion before reissuing rebuilds (check indexbuilds/logs)
- Serialize index operations in automation scripts
- Avoid aggressive retries around REBUILD INDEXES
- Restart node only if a build is provably hung
When it happens
Trigger: Calling rebuild of an index (REBUILD INDEXES / buildIndexesBlocking / createIndex path) while the same index is still building — e.g. issuing `nodetool rebuild_index` twice, or creating an index while its initial build is running.
Common situations: Ops re-running a stuck-seeming REBUILD INDEXES without waiting; schema-change and manual rebuild racing after node restart; scripted retries firing while the first build is still active.
Related errors
- Node is still rebuilding. Check nodetool netstats.
- Bootstrap can be started exactly once, but seems to have alr
- Transfer of stream %s already completed or aborted (perhaps
- Index build of {} failed. Please run full index rebuild to f
- Queue is empty
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/d33bb67e65127017.
Report an issue: GitHub.