ipfs/kubo · error
could not read versions: %w
Error message
could not read versions: %w
What it means
DistVersions reads the version list for a distribution via a bufio.Scanner and parses each line with semver. If the scanner encounters an I/O or read error mid-scan (scan.Err() != nil), the versions list is incomplete and the read failure is wrapped as "could not read versions". Note it reflects scanner/read failures, not individual unparseable lines (those are skipped with continue).
Source
Thrown at repo/fsrepo/migrations/versions.go:60
func DistVersions(ctx context.Context, fetcher Fetcher, dist string, sortDesc bool) ([]string, error) {
versionBytes, err := fetcher.Fetch(ctx, path.Join(dist, distVersions))
if err != nil {
return nil, err
}
prefix := "v"
var vers []semver.Version
scan := bufio.NewScanner(bytes.NewReader(versionBytes))
for scan.Scan() {
ver, err := semver.Make(strings.TrimLeft(scan.Text(), prefix))
if err != nil {
continue
}
vers = append(vers, ver)
}
if scan.Err() != nil {
return nil, fmt.Errorf("could not read versions: %w", scan.Err())
}
if sortDesc {
sort.Sort(sort.Reverse(semver.Versions(vers)))
} else {
sort.Sort(semver.Versions(vers))
}
out := make([]string, len(vers))
for i := range vers {
out[i] = prefix + vers[i].String()
}
return out, nil
}
View on GitHub (pinned to 329838acdf)
Solutions
- Retry the request — the wrapped scan.Err() is usually a transient network failure.
- Check connectivity to the distribution endpoint (curl the versions URL) to rule out proxy/firewall blocking.
- Inspect the wrapped %w error for the root cause (connection reset, TLS handshake, timeout) and address it.
- Configure or wrap the fetcher with sane timeouts/retries before calling DistVersions.
Defensive patterns
Strategy: retry
Try / catch
var vers []string
var err error
for i := 0; i < 3; i++ {
vers, err = migrations.DistVersions(ctx, fetcher, dist, false)
if err == nil || !isTransientReadErr(err) {
break
}
select {
case <-time.After(time.Duration(i+1) * time.Second):
case <-ctx.Done():
return ctx.Err()
}
}
if err != nil {
return fmt.Errorf("could not read versions: %w", err)
} Prevention
- Wrap fetchers with timeouts and bounded retries for transient network faults.
- Check connectivity/proxy settings when failures repeat.
- Use a context with a deadline so retries abort cleanly.
When it happens
Trigger: Calling DistVersions (directly or via LatestDistVersion / fetchBinary flows) when the underlying reader breaks mid-read: network connection reset while streaming the version file, TLS failure, or an aborted response body from the dist server.
Common situations: Flaky or proxied network connections dropping mid-download, dist server timeouts, firewall/VPN interference, or transient DNS/TLS issues when reaching the distribution endpoint.
Related errors
- reading download: %w
- could not find a non dev version
- e (stream error trailer header value)
- no local swarm address for migration node
- could not connect to migration peer %q: %s
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/e0916620572e85a3.
Report an issue: GitHub.