ipfs/kubo · warning
fast-provide: %w
Error message
fast-provide: %w
What it means
ExecuteFastProvideRoot wraps a failure from the synchronous DHT provide of a root CID. When the 'wait' mode is selected, provideCIDSync blocks until the DHT client announces the CID; any underlying error (no DHT client, RPC failure, timeout) is wrapped as 'fast-provide: %w'. In async mode errors are only logged, so this error only surfaces from sync runs.
Source
Thrown at core/commands/cmdenv/env.go:172
}
// Check if strategy allows providing this content
strategyStr := cfg.Provide.Strategy.WithDefault(config.DefaultProvideStrategy)
strategy := config.MustParseProvideStrategy(strategyStr)
shouldProvide := config.ShouldProvideForStrategy(strategy, isPinned, isPinnedRoot, isMFS)
if !shouldProvide {
log.Debugw("fast-provide-root: skipped", "reason", "strategy does not match content", "strategy", strategyStr, "pinned", isPinned, "pinnedRoot", isPinnedRoot, "mfs", isMFS)
return nil
}
// Execute provide operation
if wait {
// Synchronous mode: block until provide completes, return error on failure
log.Debugw("fast-provide-root: providing synchronously", "cid", rootCid)
if err := provideCIDSync(ctx, ipfsNode.DHTClient, rootCid); err != nil {
log.Warnw("fast-provide-root: sync provide failed", "cid", rootCid, "error", err)
return fmt.Errorf("fast-provide: %w", err)
}
log.Debugw("fast-provide-root: sync provide completed", "cid", rootCid)
return nil
}
// Asynchronous mode (default): fire-and-forget, don't block, always return nil.
// Parent off the node's lifetime context (not context.Background) so the
// goroutine cancels on daemon shutdown instead of potentially outliving
// the node and touching a closed DHT client. The timeout still bounds
// stuck DHT operations.
log.Debugw("fast-provide-root: providing asynchronously", "cid", rootCid)
go func() {
ctx, cancel := context.WithTimeout(ipfsNode.Context(), config.DefaultFastProvideTimeout)
defer cancel()
if err := provideCIDSync(ctx, ipfsNode.DHTClient, rootCid); err != nil {
log.Warnw("fast-provide-root: async provide failed", "cid", rootCid, "error", err)
} else {
log.Debugw("fast-provide-root: async provide completed", "cid", rootCid)View on GitHub (pinned to 329838acdf)
Solutions
- Inspect the wrapped cause (%w) — fix the underlying DHT/routing error first
- Ensure the daemon has DHT/routing reachable (bootstrap peers, Swarm connectivity)
- Check Provide.Strategy / Provide.Enabled config if fast-provide shouldn't run
- Use async mode (omit wait) if blocking on provide is not required; failures then log as warnings
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check: node routing reachable
if cfg.Provide.Enabled == false {
// skip fast-provide entirely
} Try / catch
err := cmdenv.ExecuteFastProvideRoot(ctx, node, rootCid, true)
if err != nil {
var cause error
errors.As(err, &cause) // unwrap 'fast-provide: %w' to see the DHT error
log.Warnf("sync provide failed: %v", cause)
} Prevention
- Verify bootstrap/DHT connectivity before sync provide
- Prefer async mode unless the announcement must complete before continuing
- Keep Provide.Strategy and Provide.Enabled config intentional and documented
When it happens
Trigger: Running `ipfs pin add` / pinning with Provide.Strategy causing a fast-provide and --provide-wait (sync) when the DHT provide RPC fails: node offline, no bootstrap/DHT peers, provide worker error, or nil DHTClient.
Common situations: Nodes behind restrictive NAT/firewalls with no reachable DHT; Provide.Enabled or routing misconfiguration; tests without bootstrap peers trying sync provide.
Related errors
- invalid provide strategy: empty token in %q
- unknown provide strategy token: %q in %q
- "all" strategy cannot be combined with other strategies in %
- +unique/+entities must combine with pinned and/or mfs in %q
- failed to check pin status for requestid=%q due to error: %v
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/ff9bcc074ed19201.
Report an issue: GitHub.