ipfs/kubo · error
%s, %w
Error message
%s, %w
What it means
A wrapper error for the failed-download case: when downloads failed AND the context was cancelled/timed out, fetchMigrations prefixes the download-failure error with the context error, using %w to preserve unwrapping of the inner download error.
Source
Thrown at repo/fsrepo/migrations/migrations.go:315
logger.Printf("could not download %s: %s", name, err)
return
}
logger.Printf("Downloaded and unpacked migration: %s (%s)", loc, ver)
bins[i] = loc
}(i, name)
}
wg.Wait()
var fails []string
for i := range bins {
if bins[i] == "" {
fails = append(fails, needed[i])
}
}
if len(fails) != 0 {
err = fmt.Errorf("failed to download migrations: %s", strings.Join(fails, " "))
if ctx.Err() != nil {
err = fmt.Errorf("%s, %w", ctx.Err(), err)
}
return nil, err
}
return bins, nil
}
// RunHybridMigrations intelligently runs migrations using external tools for legacy versions
// and embedded migrations for modern versions. This handles the transition from external
// fs-repo-migrations binaries (for repo versions <16) to embedded migrations (for repo versions ≥16).
//
// The function automatically:
// 1. Uses external migrations to get from current version to v16 (if needed)
// 2. Uses embedded migrations for v16+ steps
// 3. Handles pure external, pure embedded, or mixed migration scenarios
//
// Legacy external migrations (repo versions <16) only support HTTPS downloads.
//View on GitHub (pinned to 329838acdf)
Solutions
- Re-run the migration with an adequate timeout and without cancelling the daemon
- Use `ipfs daemon --migrate` interactively and wait for completion
- Check errors.Is(err, context.DeadlineExceeded)/Canceled to confirm the cancellation, then address why it was cancelled
- Increase systemd TimeoutStartSec or supervisor stop/start timeouts around the daemon
Example fix
// before ctx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() err := migration.RunMigration(ctx, fetcher, ver, dir, false) // after ctx, cancel := context.WithTimeout(ctx, 15*time.Minute) // migrations can be slow defer cancel() err := migration.RunMigration(ctx, fetcher, ver, dir, false)
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the context has generous time before calling timeout := 15 * time.Minute ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel()
Try / catch
if err != nil {
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
log.Println("migration aborted: context cancelled; re-run without interruption")
}
return err
} Prevention
- Give migrations long timeouts (they download and run many binaries)
- Avoid wrapping RunMigration in short-lived request contexts
- Increase systemd TimeoutStartSec for the daemon
- Don't Ctrl-C mid-migration; wait for completion
When it happens
Trigger: The context passed to fetchMigrations (via RunMigration) is cancelled or times out while/after some migration downloads fail — e.g. user hits Ctrl-C during `ipfs daemon --migrate`, or a parent timeout expires mid-download.
Common situations: Daemon startup with a systemd/supervisor timeout that cancels migration context; Ctrl-C during a long download; test harness context deadlines.
Related errors
- cannot get migrations from unknown fetcher type
- nothing downloaded by ipfs fetcher
- no local swarm address for migration node
- could not connect to migration peer %q: %s
- not a file node: %q
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/7c03635d573f7867.
Report an issue: GitHub.