{"record":{"id":"9dcfcf963a6587fe","repo":"dgraph-io/dgraph","slug":"expecting-first-key-to-be-schema-key-v","errorCode":null,"errorMessage":"Expecting first key to be schema key: %+v","messagePattern":"Expecting first key to be schema key: %\\+v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"worker/predicate_move.go","lineNumber":81,"sourceCode":"\tproposal := &pb.Proposal{}\n\tsize := 0\n\tvar pk x.ParsedKey\n\n\tfor kvPayload := range kvs {\n\t\tbuf := z.NewBufferSlice(kvPayload.GetData())\n\t\terr := buf.SliceIterate(func(s []byte) error {\n\t\t\tkv := &bpb.KV{}\n\t\t\tx.Check(proto.Unmarshal(s, kv))\n\t\t\tif len(pk.Attr) == 0 {\n\t\t\t\t// This only happens once.\n\t\t\t\tvar err error\n\t\t\t\tpk, err = x.Parse(kv.Key)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn errors.Errorf(\"while parsing kv: %+v, got error: %v\", kv, err)\n\t\t\t\t}\n\n\t\t\t\tif !pk.IsSchema() {\n\t\t\t\t\treturn errors.Errorf(\"Expecting first key to be schema key: %+v\", kv)\n\t\t\t\t}\n\n\t\t\t\t// Delete on all nodes. Remove the schema at timestamp kv.Version-1 and set it at\n\t\t\t\t// kv.Version. kv.Version will be the TxnTs of the predicate move.\n\t\t\t\tp := &pb.Proposal{CleanPredicate: pk.Attr, StartTs: kv.Version - 1}\n\t\t\t\tglog.Infof(\"Predicate being received: %v\", pk.Attr)\n\t\t\t\tif err := n.proposeAndWait(ctx, p); err != nil {\n\t\t\t\t\tglog.Errorf(\"Error while cleaning predicate %v %v\\n\", pk.Attr, err)\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tproposal.Kv = append(proposal.Kv, kv)\n\t\t\tsize += len(kv.Key) + len(kv.Value)\n\t\t\tif size >= 32<<20 { // 32 MB\n\t\t\t\tif err := n.proposeAndWait(ctx, proposal); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/worker/predicate_move.go#L63-L99","documentation":"During a predicate move, the destination group expects the FIRST KV streamed by the source leader to be the predicate's schema key (so it can clean the old predicate and set schema at kv.Version). If x.Parse succeeds but pk.IsSchema() is false, this error aborts the move, because applying data keys before the schema would leave the destination inconsistent.","triggerScenarios":"ReceivePredicate/batchAndProposeKeyValues on the destination Alpha receives a stream whose first KV is a data/posting key instead of a schema key — e.g. a sender that doesn't order schema first, a move implemented by external tooling replaying KVs, or a partial move restarted mid-stream skipping the schema KV.","commonSituations":"Custom/patched sender code streaming tablet KVs without the schema key prefix; resuming an interrupted move at the wrong offset; version mismatch altering key ordering between Alphas.","solutions":["Restart the predicate move from scratch so the full stream (schema first) is delivered.","Verify the sender iterates the badger stream with schema keys ordered first (default IterationOrder for predicate moves).","Ensure source and destination Alpha versions match.","If using custom tooling, prepend the schema KV for the predicate before data KVs."],"exampleFix":"// before: streaming data KVs only\nstreamKVs(predicate, opts{SkipSchema: true})\n// after\nstreamKVs(predicate, opts{SkipSchema: false}) // schema key must come first","handlingStrategy":"validation","validationCode":"pk, err := x.Parse(kv.Key)\nif err == nil && !pk.IsSchema() {\n\treturn errors.New(\"stream must start with the predicate's schema key\")\n}","typeGuard":"func isSchemaKey(key []byte) bool {\n\tpk, err := x.Parse(key)\n\treturn err == nil && pk.IsSchema()\n}","tryCatchPattern":"if strings.Contains(err.Error(), \"Expecting first key to be schema key\") {\n\t// restart the move from scratch so schema KV is streamed first\n}","preventionTips":["Always stream the schema KV first when moving a predicate","Use the built-in MovePredicate path rather than custom KV replay","Do not resume interrupted moves at arbitrary offsets","Pin identical Dgraph versions on both Alphas involved in the move"],"tags":["dgraph","predicate-move","schema","streaming"],"backgroundTag":"schema-key-missing","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}