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

  1. Re-run the migration with an adequate timeout and without cancelling the daemon
  2. Use `ipfs daemon --migrate` interactively and wait for completion
  3. Check errors.Is(err, context.DeadlineExceeded)/Canceled to confirm the cancellation, then address why it was cancelled
  4. 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

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


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