apache/druid · error · IllegalStateException

Cannot start; not ready!

Error message

Cannot start; not ready!

What it means

AbstractBatchIndexTask.setup calls isReady(...) purely for its side effects (initializing taskLockHelper) before running the task, expecting it to return true. If isReady returns false — meaning the task cannot acquire its required locks or its preconditions are unmet — the task cannot start, so this ISE is thrown. Subclasses define readiness (usually: no conflicting locks exist for my intervals).

Source

Thrown at indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractBatchIndexTask.java:178

  /**
   * Run this task. Before running the task, it checks the current task is already stopped and
   * registers a cleaner to interrupt the thread running this task on abnormal exits.
   *
   * @see #runTask(TaskToolbox)
   * @see #stopGracefully(TaskConfig)
   */
  @Override
  public String setup(TaskToolbox toolbox) throws Exception
  {
    if (taskLockHelper == null) {
      // Subclasses generally use "isReady" to initialize the taskLockHelper. It's not guaranteed to be called before
      // "run", and so we call it here to ensure it happens.
      //
      // We're only really calling it for its side effects, and we expect it to return "true". If it doesn't, something
      // strange is going on, so bail out.
      if (!isReady(toolbox.getTaskActionClient())) {
        throw new ISE("Cannot start; not ready!");
      }
    }

    synchronized (this) {
      if (stopped) {
        return "Attempting to run a task that has been stopped. See overlord & task logs for more details.";
      } else {
        // Register the cleaner to interrupt the current thread first.
        // Since the resource closer cleans up the registered resources in LIFO order,
        // this will be executed last on abnormal exists.
        // The order is sometimes important. For example, Appenderator has two methods of close() and closeNow(), and
        // closeNow() is supposed to be called on abnormal exits. Interrupting the current thread could lead to close()
        // to be called indirectly, e.g., for Appenderators in try-with-resources. In this case, closeNow() should be
        // called before the current thread is interrupted, so that subsequent close() calls can be ignored.
        final Thread currentThread = Thread.currentThread();
        resourceCloserOnAbnormalExit.register(config -> currentThread.interrupt());
      }
    }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Check competing tasks: GET /druid/indexer/v1/tasks and look for active tasks on the same datasource/interval; wait for or kill them, then retry the task.
  2. Inspect task locks via the overlord locking endpoints and clear stale locks (restart overlord or wait for lock expiry).
  3. If a custom task subclass, ensure isReady() returns true after initialization and doesn't permanently return false.
  4. Retry the task after the conflicting task completes; Druid usually queues/retries automatically when locks are unavailable.

Example fix

// before
// task submitted while overlapping batch task still running -> setup() fails
// after
// wait for/kill the overlapping task, then resubmit:
curl -X DELETE http://overlord:8081/druid/indexer/v1/task/<conflictingTaskId>/shutdown
Defensive patterns

Strategy: retry

Validate before calling

// before submitting, check for conflicting active tasks on the same datasource/interval
curl -s http://overlord:8081/druid/indexer/v1/tasks | jq '[.[] | select(.dataSource=="my_ds")]'

Try / catch

try {
  runTask(task);
} catch (IllegalStateException e) {
  if ("Cannot start; not ready!".equals(e.getMessage())) {
    // wait for competing tasks to finish, then resubmit
  } else throw e;
}

Prevention

When it happens

Trigger: Running a batch task whose isReady() returns false because another task holds a conflicting lock for the same datasource/interval, or a subclass whose isReady was overridden to return false for incomplete initialization.

Common situations: Submitting a compaction or batch ingestion task while an earlier overlapping task still holds locks; two tasks targeting the same time chunk concurrently; stale locks left after an overlord failover.

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/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/9aec8d7bcf340707. Report an issue: GitHub.