ipfs/kubo · error

failed to get migration fetcher: %w

Error message

failed to get migration fetcher: %w

What it means

After reading the migration config, RunHybridMigrations builds a fetcher with GetMigrationFetcher; a failure (e.g. no download sources configured) is wrapped with this message and aborts the external network-download fallback path.

Source

Thrown at repo/fsrepo/migrations/migrations.go:405

				foundAll = false
				break
			}
		}

		if foundAll {
			return runMigrationsFromPath(ctx, migrations, binPaths, ipfsDir, logger, false)
		}

		// Fall back to network download (original behavior)
		migrationCfg, err := ReadMigrationConfig(ipfsDir, "")
		if err != nil {
			return fmt.Errorf("could not read migration config: %w", err)
		}

		// Use existing RunMigration which handles network downloads properly (HTTPS only for legacy migrations)
		fetcher, err := GetMigrationFetcher(migrationCfg.DownloadSources, GetDistPathEnv(CurrentIpfsDist), nil)
		if err != nil {
			return fmt.Errorf("failed to get migration fetcher: %w", err)
		}
		defer fetcher.Close()
		return RunMigration(ctx, fetcher, targetVer, ipfsDir, allowDowngrade)
	}

	// Case 3: Hybrid migration (current < 16, target ≥ 16)
	if needsExternal && needsEmbedded {
		logger.Printf("Starting hybrid migration from version %d to %d", currentVer, targetVer)
		logger.Print("Using hybrid migration strategy: external to v16, then embedded")

		// Phase 1: Use external migrations to get to v16
		logger.Printf("Phase 1: External migration from v%d to v%d", currentVer, embeddedMigrationsMinVersion)

		// Check for external migration binaries in PATH first
		migrations, binPaths, err := findMigrations(ctx, currentVer, embeddedMigrationsMinVersion)
		if err != nil {
			return fmt.Errorf("could not determine external migration paths: %w", err)
		}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Set DownloadSources in the migration config or unset a bad IPFS_DIST_PATH to use the default dist endpoint
  2. Verify network reachability of the configured distribution source
  3. For air-gapped systems, place migration binaries in PATH or the migrations dir so the download path isn't needed
  4. Check the inner error for the exact fetcher failure

Example fix

// before
export IPFS_DIST_PATH=""   # with empty DownloadSources in config
// after
export IPFS_DIST_PATH="https://dist.ipfs.tech"
# or populate DownloadSources in IPFS_PATH migrations config
Defensive patterns

Strategy: validation

Validate before calling

if len(cfg.DownloadSources) == 0 && os.Getenv("IPFS_DIST_PATH") == "" {
    log.Println("no download source configured; binaries in PATH will be required")
}

Try / catch

if err != nil && strings.Contains(err.Error(), "failed to get migration fetcher") {
    return fmt.Errorf("set DownloadSources or IPFS_DIST_PATH to a reachable dist mirror: %w", err)
}

Prevention

When it happens

Trigger: GetMigrationFetcher(migrationCfg.DownloadSources, GetDistPathEnv(CurrentIpfsDist), nil) returns an error — most commonly an empty DownloadSources list, or a bad IPFS_DIST_PATH value.

Common situations: Migration config with empty DownloadSources; IPFS_DIST_PATH set to an unusable value; users blocking all download mirrors on air-gapped systems.

Related errors


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