{"record":{"id":"2c2a69eb3504498b","repo":"dgraph-io/dgraph","slug":"could-not-read-list-part-with-key-s","errorCode":null,"errorMessage":"could not read list part with key %s","messagePattern":"could not read list part with key (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"posting/list.go","lineNumber":2274,"sourceCode":"\t\treturn nil, errors.Wrapf(err, \"cannot retrieve facet\")\n\t}\n\tfcs = append(fcs, &pb.Facets{Facets: facets.CopyFacets(p.Facets, param)})\n\treturn fcs, nil\n}\n\n// readListPart reads one split of a posting list from Badger.\nfunc (l *List) readListPart(startUid uint64) (*pb.PostingList, error) {\n\tkey, err := x.SplitKey(l.key, startUid)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err,\n\t\t\t\"cannot generate key for list with base key %s and start UID %d\",\n\t\t\thex.EncodeToString(l.key), startUid)\n\t}\n\ttxn := pstore.NewTransactionAt(l.minTs, false)\n\tdefer txn.Discard()\n\titem, err := txn.Get(key)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"could not read list part with key %s\",\n\t\t\thex.EncodeToString(key))\n\t}\n\tpart := &pb.PostingList{}\n\tif err := unmarshalOrCopy(part, item); err != nil {\n\t\treturn nil, errors.Wrapf(err, \"cannot unmarshal list part with key %s\",\n\t\t\thex.EncodeToString(key))\n\t}\n\treturn part, nil\n}\n\n// shouldSplit returns true if the given plist should be split in two.\nfunc shouldSplit(plist *pb.PostingList) bool {\n\treturn proto.Size(plist) >= maxListSize && len(plist.Pack.Blocks) > 1\n}\n\nfunc (out *rollupOutput) updateSplits() {\n\tif out.plist == nil || len(out.parts) > 0 {\n\t\tout.plist = &pb.PostingList{}","sourceCodeStart":2256,"sourceCodeEnd":2292,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/posting/list.go#L2256-L2292","documentation":"This error wraps a lower-level badger failure that occurred while reading one part (chunk) of a multi-part posting list stored in Dgraph. Posting lists larger than the configured value capacity are split into parts keyed by the list key plus a suffix; reading a part that should exist failed. The wrap adds the hex-encoded part key so the specific unreadable chunk can be located.","triggerScenarios":"Calling readListPart (via List iteration, rollup, or query evaluation) when txn.Get(key) fails inside a transaction pinned at l.minTs — e.g. the part was garbage-collected, the key was never written, or the underlying badger read returned an I/O/corruption error.","commonSituations":"Badger DB corruption or missing value-log files after an unclean shutdown; reading at a timestamp older than retained versions (too-aggressive GC); manual deletion of badger files; disk errors.","solutions":["Run badger integrity checks and restore from backup if the value log is corrupt","Lower value-log GC aggressiveness / ensure DiscardTs is not set past needed versions","Retry after rollup rebuilds the posting list (trigger a rollup over the affected key)","Check disk health and badger logs for the underlying error cause"],"exampleFix":"// before\nitem, err := txn.Get(key)\nif err != nil {\n    return nil, errors.Wrapf(err, \"could not read list part with key %s\", hex.EncodeToString(key))\n}\n// after: log the underlying error and key, then retry via rollup or fail loudly\nitem, err := txn.Get(key)\nif err != nil {\n    if errors.Is(err, badger.ErrKeyNotFound) {\n        return nil, errors.Wrapf(err, \"list part missing (possibly GC'd or rollup pending) key %s\", hex.EncodeToString(key))\n    }\n    return nil, errors.Wrapf(err, \"could not read list part with key %s\", hex.EncodeToString(key))\n}","handlingStrategy":"retry","validationCode":"// Pre-check: read the list at a recent readTs and confirm the part exists\nfunc partExists(kv *badger.DB, key []byte, readTs uint64) bool {\n    txn := kv.NewTransactionAt(readTs, false)\n    defer txn.Discard()\n    _, err := txn.Get(key)\n    return err == nil\n}","typeGuard":null,"tryCatchPattern":"// Retry read after rollup; surface underlying error\npart, err := readListPart(key, startUid)\nif err != nil {\n    if isRetryable(err) { // badger I/O or transient ts issues\n        triggerRollup(key)\n        part, err = readListPart(key, startUid)\n    }\n    if err != nil { return fmt.Errorf(\"list part %x unreadable: %w\", key, err) }\n}","preventionTips":["Do not run badger value-log GC more aggressively than Dgraph's watermark handling allows","Never manually delete or edit badger directory files","Monitor disk health and badger error logs","Keep all Alphas on the same Dgraph/badger version"],"tags":["storage","badger","corruption"],"backgroundTag":"posting-list-read-failed","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}