{"record":{"id":"cbcac54028881c5b","repo":"ipfs/kubo","slug":"failed-to-get-migration-fetcher-w","errorCode":null,"errorMessage":"failed to get migration fetcher: %w","messagePattern":"failed to get migration fetcher: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"repo/fsrepo/migrations/migrations.go","lineNumber":405,"sourceCode":"\t\t\t\tfoundAll = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif foundAll {\n\t\t\treturn runMigrationsFromPath(ctx, migrations, binPaths, ipfsDir, logger, false)\n\t\t}\n\n\t\t// Fall back to network download (original behavior)\n\t\tmigrationCfg, err := ReadMigrationConfig(ipfsDir, \"\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"could not read migration config: %w\", err)\n\t\t}\n\n\t\t// Use existing RunMigration which handles network downloads properly (HTTPS only for legacy migrations)\n\t\tfetcher, err := GetMigrationFetcher(migrationCfg.DownloadSources, GetDistPathEnv(CurrentIpfsDist), nil)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to get migration fetcher: %w\", err)\n\t\t}\n\t\tdefer fetcher.Close()\n\t\treturn RunMigration(ctx, fetcher, targetVer, ipfsDir, allowDowngrade)\n\t}\n\n\t// Case 3: Hybrid migration (current < 16, target ≥ 16)\n\tif needsExternal && needsEmbedded {\n\t\tlogger.Printf(\"Starting hybrid migration from version %d to %d\", currentVer, targetVer)\n\t\tlogger.Print(\"Using hybrid migration strategy: external to v16, then embedded\")\n\n\t\t// Phase 1: Use external migrations to get to v16\n\t\tlogger.Printf(\"Phase 1: External migration from v%d to v%d\", currentVer, embeddedMigrationsMinVersion)\n\n\t\t// Check for external migration binaries in PATH first\n\t\tmigrations, binPaths, err := findMigrations(ctx, currentVer, embeddedMigrationsMinVersion)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"could not determine external migration paths: %w\", err)\n\t\t}","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/repo/fsrepo/migrations/migrations.go#L387-L423","documentation":"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.","triggerScenarios":"GetMigrationFetcher(migrationCfg.DownloadSources, GetDistPathEnv(CurrentIpfsDist), nil) returns an error — most commonly an empty DownloadSources list, or a bad IPFS_DIST_PATH value.","commonSituations":"Migration config with empty DownloadSources; IPFS_DIST_PATH set to an unusable value; users blocking all download mirrors on air-gapped systems.","solutions":["Set DownloadSources in the migration config or unset a bad IPFS_DIST_PATH to use the default dist endpoint","Verify network reachability of the configured distribution source","For air-gapped systems, place migration binaries in PATH or the migrations dir so the download path isn't needed","Check the inner error for the exact fetcher failure"],"exampleFix":"// before\nexport IPFS_DIST_PATH=\"\"   # with empty DownloadSources in config\n// after\nexport IPFS_DIST_PATH=\"https://dist.ipfs.tech\"\n# or populate DownloadSources in IPFS_PATH migrations config","handlingStrategy":"validation","validationCode":"if len(cfg.DownloadSources) == 0 && os.Getenv(\"IPFS_DIST_PATH\") == \"\" {\n    log.Println(\"no download source configured; binaries in PATH will be required\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"failed to get migration fetcher\") {\n    return fmt.Errorf(\"set DownloadSources or IPFS_DIST_PATH to a reachable dist mirror: %w\", err)\n}","preventionTips":["Configure at least one reachable DownloadSources entry","Sanity-check IPFS_DIST_PATH values","For air-gapped nodes, rely on local binaries instead of fetchers","Test fetcher creation before launching long migrations"],"tags":["migrations","fetcher","configuration"],"backgroundTag":"migration-fetcher-unavailable","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}