dgraph-io/dgraph · critical

StartTs must be provided

Error message

StartTs must be provided

What it means

Raised in applyMutations (worker/draft.go:428) when a committed mutation proposal arrives with StartTs == 0. Every mutation must carry the transaction's start timestamp for watermark/index tracking; zero means the proposal was malformed.

Source

Thrown at worker/draft.go:428

		}

		// Propose initial types as well after a drop all as they would have been cleared.
		initialTypes := schema.InitialTypes(x.RootNamespace)
		for _, t := range initialTypes {
			if err := updateType(t.GetTypeName(), t, 1); err != nil {
				return err
			}
		}

		return nil
	}

	if proposal.Mutations.DropOp == pb.Mutations_TYPE {
		return schema.State().DeleteType(proposal.Mutations.DropValue, proposal.StartTs)
	}

	if proposal.Mutations.StartTs == 0 {
		return errors.New("StartTs must be provided")
	}

	if len(proposal.Mutations.Schema) > 0 || len(proposal.Mutations.Types) > 0 {
		// MaxAssigned would ensure that everything that's committed up until this point
		// would be picked up in building indexes. Any uncommitted txns would be cancelled
		// by detectPendingTxns below.
		startTs := posting.Oracle().MaxAssigned()

		span.AddEvent("Applying schema and types")
		for _, supdate := range proposal.Mutations.Schema {
			// We should not need to check for predicate move here.
			if err := detectPendingTxns(supdate.Predicate); err != nil {
				return err
			}
		}

		if err := runSchemaMutation(ctx, proposal.Mutations.Schema, startTs); err != nil {
			return err

View on GitHub (pinned to 759e242be6)

Solutions

  1. Ensure all Dgraph alpha/zero nodes run the same version; upgrade or downgrade to a consistent release.
  2. Regenerate/fix the proposal producer so StartTs is populated from txn.RunAtTs.
  3. If a single bad proposal is wedging the group, restart the affected alpha; the proposal will be skipped or retried cleanly.

Example fix

// before
proposal := &pb.Mutations{Schema: sch}
// after: always set StartTs
proposal := &pb.Mutations{Schema: sch, StartTs: startTs}
Defensive patterns

Strategy: validation

Validate before calling

if proposal.Mutations == nil || proposal.Mutations.StartTs == 0 { return errors.New("proposal missing StartTs") }

Type guard

func validMutationProposal(m *pb.Mutations) bool {
    return m != nil && m.StartTs != 0
}

Prevention

When it happens

Trigger: A peer or client submits a Mutations proposal to Raft with StartTs unset (0) — usually from buggy or version-mismatched alpha code, not from end-user API calls.

Common situations: Mixed cluster versions where an older alpha sends proposals the newer server considers incomplete; custom tooling writing directly to the internal Raft proposal API; corrupted task queue entries.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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