dgraph-io/dgraph · warning

Pending transactions found. Please retry operation

Error message

Pending transactions found. Please retry operation

What it means

errHasPendingTxns, returned by detectPendingTxns (worker/draft.go:310). Mutating operations (drop all, restore start) applied through Raft abort when there are still pending (uncommitted or un-aborted) transactions at the time the proposal applies. The client is told to retry once those transactions have been aborted/finished.

Source

Thrown at worker/draft.go:310

	var cc raftpb.ConfChange
	if err := cc.Unmarshal(e.Data); err != nil {
		glog.Errorf("While unmarshalling confchange: %+v", err)
	}

	if cc.Type == raftpb.ConfChangeRemoveNode {
		n.DeletePeer(cc.NodeID)
	} else if len(cc.Context) > 0 {
		var rc pb.RaftContext
		x.Check(proto.Unmarshal(cc.Context, &rc))
		n.Connect(rc.Id, rc.Addr)
	}

	cs := n.Raft().ApplyConfChange(cc)
	n.SetConfState(cs)
	n.DoneConfChange(cc.ID, nil)
}

var errHasPendingTxns = errors.New("Pending transactions found. Please retry operation")

// We must not wait here. Previously, we used to block until we have aborted the
// transactions. We're now applying all updates serially, so blocking for one
// operation is not an option.
func detectPendingTxns(attr string) error {
	tctxs := posting.Oracle().IterateTxns(func(key []byte) bool {
		pk, err := x.Parse(key)
		if err != nil {
			glog.Errorf("error %v while parsing key %v", err, hex.EncodeToString(key))
			return false
		}
		return pk.Attr == attr
	})
	if len(tctxs) == 0 {
		return nil
	}
	go tryAbortTransactions(tctxs)
	return errHasPendingTxns

View on GitHub (pinned to 759e242be6)

Solutions

  1. Retry the operation after a short backoff — the message explicitly says to retry; pending txns get aborted automatically.
  2. Pause application writes/queries during drop-all or restore to prevent new pending transactions.
  3. If it persists, restart the node to clear stuck transaction state and retry.
  4. Investigate long-running transactions holding the oracle watermark.

Example fix

// before: one-shot drop that can fail
client.DropAll()
// after: retry on pending-txn error
for i := 0; i < 5; i++ {
    err := client.DropAll()
    if err == nil || !strings.Contains(err.Error(), "Pending transactions") { break }
    time.Sleep(time.Duration(1<<i) * time.Second)
}
Defensive patterns

Strategy: retry

Try / catch

for i := 0; i < 5; i++ {
    err := client.DropAll()
    if err == nil || !strings.Contains(err.Error(), "Pending transactions") {
        return err
    }
    time.Sleep(time.Duration(1<<i) * time.Second)
}
return errors.New("drop-all kept failing: pending txns")

Prevention

When it happens

Trigger: Running DropAll/DropData or a restore while another transaction holds watermarks: posting.Oracle().IterateTxns finds non-empty pending transaction contexts at apply time.

Common situations: Dropping all data while queries/writes are in flight; starting a restore while open transactions exist; heavy write load during maintenance operations.

Related errors


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