dgraph-io/dgraph · warning

another operation is already running

Error message

another operation is already running

What it means

Raised in startTaskAtTs (worker/draft.go:139) when a rollup operation is requested but the node already has one or more operations registered in n.ops. Dgraph permits only one operation task of certain kinds at a time; rollup refuses to start while any other operation is active.

Source

Thrown at worker/draft.go:139

		n.opsLock.Lock()
		delete(n.ops, id)
		n.opsLock.Unlock()
		glog.Infof("Operation completed with id: %s", id)

		// Resume rollups if another operation is being stopped.
		if id != opRollup {
			time.Sleep(10 * time.Second) // Wait for 10s to start rollup operation.
			// If any other operation is running, this would error out. This error can
			// be safely ignored because rollups will resume once that other task is done.
			_, _ = n.startTask(opRollup)
		}
	}

	closer := z.NewCloser(1)
	switch id {
	case opRollup:
		if len(n.ops) > 0 {
			return nil, errors.Errorf("another operation is already running")
		}
		go posting.IncrRollup.Process(closer, State.GetTimestamp)
	case opRestore:
		// Restores cancel all other operations, except for other restores since
		// only one restore operation should be active any given moment.
		for otherId, otherOp := range n.ops {
			if otherId == opRestore {
				return nil, errors.Errorf("another restore operation is already running")
			}
			// Remove from map and signal the closer to cancel the operation.
			delete(n.ops, otherId)
			otherOp.SignalAndWait()
		}
	case opBackup:
		// Backup cancels all other operations, except for other backups since
		// only one backup operation should be active any given moment. Also, indexing at higher
		// timestamp can also run concurrently with backup.
		for otherId, otherOp := range n.ops {

View on GitHub (pinned to 759e242be6)

Solutions

  1. Wait for the in-flight operation to finish before starting rollup, or check its status first.
  2. If a previous operation is stuck, restart the affected Dgraph node/Zero group member to clear n.ops state.
  3. Increase the rollup cron interval so consecutive rollups do not overlap.
  4. Reduce backup/restore/indexing concurrency so rollup can acquire the single operation slot.

Example fix

// before: immediate overlapping rollup call
client.StartTask(opRollup)
// after: retry until the current operation completes
err := client.StartTask(opRollup)
if err != nil && strings.Contains(err.Error(), "another operation is already running") {
    time.Sleep(30 * time.Second)
    err = client.StartTask(opRollup)
}
Defensive patterns

Strategy: retry

Validate before calling

if activeOperations(cluster).length > 0 { throw new Skip("operation in progress") }

Try / catch

err := client.StartTask(opRollup)
if err != nil && strings.Contains(err.Error(), "another operation is already running") {
    time.Sleep(1 * time.Minute)
    return client.StartTask(opRollup)
}

Prevention

When it happens

Trigger: Calling startTask(opRollup) (via worker-task grpc/alpha operation endpoints like /alter rollup or TaskRequest) while a rollup, restore, backup, indexing, snapshot or predicate-move operation is still tracked in n.ops.

Common situations: Scheduling overlapping rollup cycles after long-running restores/backups; slow rollups on large predicates that outlast the cron interval; multiple admins triggering rollup concurrently.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/d6de842918a036c4. Report an issue: GitHub.