dgraph-io/dgraph · error
Predicate not specified
Error message
Predicate not specified
What it means
errEmptyPredicate is returned by MovePredicate in the dgraph worker package when a move-tablet request carries an empty predicate name. Dgraph refuses to start a predicate move without an explicit predicate, since it must know which tablet/keyspace to stream between groups.
Source
Thrown at worker/predicate_move.go:35
"github.com/golang/glog"
"github.com/pkg/errors"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
"google.golang.org/protobuf/proto"
"github.com/dgraph-io/badger/v4"
bpb "github.com/dgraph-io/badger/v4/pb"
"github.com/dgraph-io/dgo/v250/protos/api"
"github.com/dgraph-io/dgraph/v25/posting"
"github.com/dgraph-io/dgraph/v25/protos/pb"
"github.com/dgraph-io/dgraph/v25/schema"
"github.com/dgraph-io/dgraph/v25/tok/hnsw"
"github.com/dgraph-io/dgraph/v25/x"
"github.com/dgraph-io/ristretto/v2/z"
)
var (
errEmptyPredicate = errors.Errorf("Predicate not specified")
errNotLeader = errors.Errorf("Server is not leader of this group")
emptyPayload = api.Payload{}
)
// size of kvs won't be too big, we would take care before proposing.
func populateKeyValues(ctx context.Context, kvs []*bpb.KV) error {
glog.Infof("Writing %d keys\n", len(kvs))
if len(kvs) == 0 {
return nil
}
writer := posting.NewTxnWriter(pstore)
if err := writer.Write(&bpb.KVList{Kv: kvs}); err != nil {
return err
}
if err := writer.Flush(); err != nil {
return err
}
pk, err := x.Parse(kvs[0].Key)View on GitHub (pinned to 759e242be6)
Solutions
- Identify the Zero request that carried the empty predicate from logs and check why tablet state has a blank pred.
- Restart Zero to rebuild consistent internal tablet state.
- If from custom tooling, ensure the MoveTablet/MovePredicate request always sets the Pred field before calling.
- Upgrade to a fixed Dgraph release if this arises during normal Zero rebalancing.
Example fix
// before
req := &pb.MoveTabletRequest{SourceGroupId: 1, DestGroupId: 2}
// after
req := &pb.MoveTabletRequest{SourceGroupId: 1, DestGroupId: 2, Tablet: &pb.Tablet{Predicate: "friend"}} Defensive patterns
Strategy: validation
Validate before calling
func validateMove(req *pb.MoveTabletRequest) error {
if req == nil || req.Tablet == nil || req.Tablet.Predicate == "" {
return errors.New("predicate must be set before MoveTablet")
}
return nil
} Type guard
func hasPredicate(t *pb.Tablet) bool {
return t != nil && t.Predicate != ""
} Try / catch
if err := worker.MovePredicate(ctx, pred, src, dst); err != nil {
if strings.Contains(err.Error(), "Predicate not specified") {
// reject the request upstream / fix Zero tablet state
}
} Prevention
- Never hand-edit Zero's tablet state or state.json
- Validate internal move requests set Pred before dispatching
- Keep Zero and Alpha versions in sync
- Monitor for empty-predicate tablets via `dgraph debug`
When it happens
Trigger: Calling MovePredicate via the internal MoveTablet RPC (triggered by Zero rebalancing or `movePredicates`) with pred == "" — e.g. a malformed Zero move request or a state.json/tablet entry with a blank predicate.
Common situations: Corrupt Zero internal state proposing an empty tablet move; bugs or manual edits in Zero's tablet map; custom tooling invoking the internal move API with unset fields.
Related errors
- NQuad failed sanity check. Subject: %q, Predicate: %q, Objec
- empty variable name in function call
- empty facetKeys not allowed
- group: [%d] is not a known group
- namespace: %d. No tablet found for: %s
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/357472ace411b94b.
Report an issue: GitHub.