ipfs/kubo · warning

querying datastore for stale DHT value records: %w

Error message

querying datastore for stale DHT value records: %w

What it means

Raised by deleteStaleDHTValueRecords in the one-time migration that purges pre-v0.42.0 format DHT value records from the datastore. When the initial keys-only datastore Query fails to start, the error is wrapped with this message. purgeStaleDHTValueRecords logs it and defers the purge to the next daemon start; it is non-fatal to node operation.

Source

Thrown at core/node/storage.go:208

		logger.Warnw("writing DHT value purge marker failed", "error", err)
		return
	}
	if err := ds.Sync(ctx, dhtValuePurgeDoneKey); err != nil {
		logger.Warnw("syncing DHT value purge marker failed", "error", err)
		return
	}
	if count > 0 {
		logger.Infow("purged stale DHT value records from datastore", "keys", count)
	}
}

// deleteStaleDHTValueRecords scans the whole datastore (keys only) and
// deletes old-format DHT value records in batches. It returns the number of
// deleted keys.
func deleteStaleDHTValueRecords(ctx context.Context, ds datastore.Batching) (int, error) {
	results, err := ds.Query(ctx, query.Query{Prefix: "/", KeysOnly: true})
	if err != nil {
		return 0, fmt.Errorf("querying datastore for stale DHT value records: %w", err)
	}
	defer results.Close()

	var batch datastore.Batch
	var count, pending int
	for result := range results.Next() {
		if ctx.Err() != nil {
			return count, ctx.Err()
		}
		if result.Error != nil {
			return count, fmt.Errorf("iterating datastore keys: %w", result.Error)
		}
		if !isStaleDHTValueRecordKey(result.Key) {
			continue
		}
		if batch == nil {
			batch, err = ds.Batch(ctx)
			if err != nil {

View on GitHub (pinned to 329838acdf)

Solutions

  1. Read the wrapped error in the warning log line 'purge of stale DHT value records failed'
  2. Check the repo lock isn't held by another ipfs process (pkill stale daemons)
  3. Run datastore integrity/repair tools and check disk health
  4. Restart the daemon — the purge retries automatically on next start
Defensive patterns

Strategy: retry

Validate before calling

// verify datastore opens and queries before migration
results, err := ds.Query(ctx, query.Query{Prefix: "/", KeysOnly: true})
if err != nil {
    log.Warnf("datastore unusable, purge deferred: %v", err)
}

Try / catch

_, err := deleteStaleDHTValueRecords(ctx, ds)
if err != nil && !errors.Is(err, context.Canceled) {
    log.Warnw("purge failed, will retry on next start", "error", err)
}

Prevention

When it happens

Trigger: Daemon start runs the stale-record purge; ds.Query(ctx, query.Query{Prefix:"/", KeysOnly:true}) fails immediately — datastore is locked, corrupted, or cannot open iterators.

Common situations: Corrupted badger/levelds datastore after crash, another process holding the repo lock, disk I/O errors, or read-only filesystem.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/ee312be4912cc29e. Report an issue: GitHub.