apache/cassandra · error · RuntimeException

Unable to move

Error message

Unable to move

What it means

executeNext wraps the move's streaming/metadata step; an ExecutionException from the underlying future is rethrown as RuntimeException("Unable to move", e) after marking the move as failed via StorageService.markMoveFailed(). The original cause is attached, so the root reason (streaming failure, timeout, node down) is in the cause chain. Other exceptions are marked failed and rethrown unchanged.

Source

Thrown at src/java/org/apache/cassandra/tcm/sequences/Move.java:375

                                throw new IllegalStateException("Node should be either source or destination in the movement map " + endpoints);
                        }
                    }

                    StreamResultFuture streamResult = streamPlan.execute();

                    Future<?> accordReady = AccordService.instance().epochReadyFor(metadata, EpochReady::reads);
                    Future<?> ready = FutureCombiner.allOf(streamResult, accordReady);
                    ready.get();
                    StorageService.instance.repairPaxosForTopologyChange("move");
                }
                catch (InterruptedException e)
                {
                    return continuable();
                }
                catch (ExecutionException e)
                {
                    StorageService.instance.markMoveFailed();
                    throw new RuntimeException("Unable to move", e);
                }
                catch (Exception e)
                {
                    StorageService.instance.markMoveFailed();
                    throw e;
                }

                try
                {
                    ClusterMetadataService.instance().commit(midMove);
                }
                catch (Throwable t)
                {
                    logger.warn("Exception committing midMove, will retry on next TCM epoch advance", t);
                    JVMStabilityInspector.inspectThrowable(t);
                    return continuable();
                }
                break;

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Inspect the cause chain of the RuntimeException to find the true failure (streaming error, timeout, node down)
  2. Fix the underlying issue (restart the failed node, restore connectivity, free disk space)
  3. Re-attempt the move once the cluster is healthy; Move supports retrying from a continuable state
  4. Check StorageService move-failed state and logs for the streaming session that failed

Example fix

// before
catch (ExecutionException e)
{
    StorageService.instance.markMoveFailed();
    throw new RuntimeException("Unable to move", e);
}
// after
catch (ExecutionException e)
{
    StorageService.instance.markMoveFailed();
    throw new RuntimeException("Unable to move: " + e.getCause().getMessage(), e.getCause());
}
Defensive patterns

Strategy: try-catch

Try / catch

try { move.execute(); } catch (RuntimeException e) { Throwable root = e; while (root.getCause() != null) root = root.getCause(); logger.error("Move failed, root cause: {}", root.getMessage(), root); StorageService.instance.markMoveFailed(); }

Prevention

When it happens

Trigger: Any ExecutionException surfaced by the move execution future: streaming session failure, peer node down during range transfer, timeout waiting for the move step, or a rejected transformation during the move.

Common situations: Target/source node crashes mid-move; network partition interrupts streaming; cluster busy with another topology change causing a wait/timeout; disk space exhaustion on a streaming endpoint.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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