{"record":{"id":"aefa48de2507e0b8","repo":"ipfs/kubo","slug":"iterating-datastore-keys-w","errorCode":null,"errorMessage":"iterating datastore keys: %w","messagePattern":"iterating datastore keys: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/node/storage.go","lineNumber":219,"sourceCode":"\n// deleteStaleDHTValueRecords scans the whole datastore (keys only) and\n// deletes old-format DHT value records in batches. It returns the number of\n// deleted keys.\nfunc deleteStaleDHTValueRecords(ctx context.Context, ds datastore.Batching) (int, error) {\n\tresults, err := ds.Query(ctx, query.Query{Prefix: \"/\", KeysOnly: true})\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"querying datastore for stale DHT value records: %w\", err)\n\t}\n\tdefer results.Close()\n\n\tvar batch datastore.Batch\n\tvar count, pending int\n\tfor result := range results.Next() {\n\t\tif ctx.Err() != nil {\n\t\t\treturn count, ctx.Err()\n\t\t}\n\t\tif result.Error != nil {\n\t\t\treturn count, fmt.Errorf(\"iterating datastore keys: %w\", result.Error)\n\t\t}\n\t\tif !isStaleDHTValueRecordKey(result.Key) {\n\t\t\tcontinue\n\t\t}\n\t\tif batch == nil {\n\t\t\tbatch, err = ds.Batch(ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn count, fmt.Errorf(\"creating delete batch: %w\", err)\n\t\t\t}\n\t\t}\n\t\tif err := batch.Delete(ctx, datastore.NewKey(result.Key)); err != nil {\n\t\t\treturn count, fmt.Errorf(\"batch deleting stale key %s: %w\", result.Key, err)\n\t\t}\n\t\tcount++\n\t\tpending++\n\t\tif pending >= purgeBatchSize {\n\t\t\tif err := batch.Commit(ctx); err != nil {\n\t\t\t\treturn count, fmt.Errorf(\"committing delete batch: %w\", err)","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/node/storage.go#L201-L237","documentation":"Raised by deleteStaleDHTValueRecords while consuming the results channel from a keys-only datastore Query: an individual result carries result.Error, meaning the datastore iteration hit an error mid-scan (e.g. a key/value entry is unreadable). The purge stops at that point, returning the count of keys deleted so far; the outer purgeStaleDHTValueRecords logs a warning and retries on next start.","triggerScenarios":"Mid-iteration datastore failure during the stale DHT value record purge — corrupted record in the datastore, iterator I/O error, or underlying database error surfaced per-result.","commonSituations":"Badger corruption /checksum mismatch on some entries after unclean shutdown, failing disk sectors, or datastore backend bugs.","solutions":["Identify the failing key/cause from the wrapped result.Error in logs","Run the datastore's repair/verification tooling (e.g. badger flush/check)","Back up the repo and consider datastore rebuild if corruption persists","Restart the daemon — purge resumes/retries on next start"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"if result.Error != nil {\n    return fmt.Errorf(\"iterating datastore keys: %w\", result.Error)\n}","tryCatchPattern":"count, err := deleteStaleDHTValueRecords(ctx, ds)\nif err != nil {\n    log.Warnw(\"purge incomplete\", \"deletedSoFar\", count, \"error\", err)\n    // retried automatically on next daemon start\n}","preventionTips":["Run datastore verification/repair after unclean shutdowns","Monitor for badger/levelds checksum errors in logs","Back up the repo before manual datastore surgery"],"tags":["datastore","migration","dht","purge","corruption"],"backgroundTag":"datastore-iteration-failed","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}