juanfont/headscale · error
pulling image %s: %w
Error message
pulling image %s: %w
What it means
Returned inside `ensureImageAvailable`'s retry closure when `cli.ImagePull` itself errors and the error is not classified as permanent (`isPermanentDockerPullError`). It is retried with exponential backoff up to 60s total; if backoff is exhausted the error surfaces. Permanent errors (e.g. repository not found, auth failure) abort immediately via backoff.Permanent.
Source
Thrown at cmd/hi/docker.go:560
if verbose {
log.Printf("Image %s not found locally, pulling...", imageName)
}
registryAuth, err := dockertestutil.RegistryAuth()
if err != nil {
return fmt.Errorf("resolving registry auth: %w", err)
}
_, err = backoff.Retry(
ctx,
func() (struct{}, error) {
reader, pullErr := cli.ImagePull(ctx, imageName, image.PullOptions{RegistryAuth: registryAuth})
if pullErr != nil {
if isPermanentDockerPullError(pullErr) {
return struct{}{}, backoff.Permanent(pullErr)
}
return struct{}{}, fmt.Errorf("pulling image %s: %w", imageName, pullErr)
}
defer reader.Close()
sink := io.Discard
if verbose {
sink = os.Stdout
}
_, copyErr := io.Copy(sink, reader)
if copyErr != nil {
return struct{}{}, fmt.Errorf("reading pull output: %w", copyErr)
}
return struct{}{}, nil
},
backoff.WithBackOff(backoff.NewExponentialBackOff()),
backoff.WithMaxElapsedTime(60*time.Second),
)View on GitHub (pinned to 565fd254d0)
Solutions
- Manually pull to see the real error: `docker pull golang:<version>`.
- If rate-limited: `docker login` or configure registry mirrors; consider retagging a locally cached image.
- Verify the tag exists on Docker Hub for the configured GoVersion.
- For persistent network issues, fix proxy/DNS, then re-run — retry budget is only 60s.
Defensive patterns
Strategy: retry
Validate before calling
// verify the tag exists before configuring the run
if err := exec.Command("docker", "manifest", "inspect", "golang:"+cfg.GoVersion).Run(); err != nil {
return fmt.Errorf("golang:%s is not a published tag: %w", cfg.GoVersion, err)
} Try / catch
err := ensureImageAvailable(ctx, cli, image, verbose)
if err != nil && strings.Contains(err.Error(), "pulling image") {
if strings.Contains(err.Error(), "toomanyrequests") {
// rate limited: docker login or mirror, then retry
} else if strings.Contains(err.Error(), "not found") {
// permanent: fix the tag; do not retry
}
} Prevention
- Authenticate pulls in CI to avoid Hub rate limits.
- Pre-pull images outside the test run.
- Confirm tags exist before pinning GoVersion.
- Fix proxy/DNS stability so the 60s backoff budget suffices.
When it happens
Trigger: Transient network failures to the registry; Docker Hub rate limiting (429 toomanyrequests); registry TLS issues; DNS hiccups — each retried. Non-existent tag (golang:<bad-version>) or denied repository becomes permanent and is returned unwrapped-classified.
Common situations: Unauthenticated Docker Hub pulls in CI hitting rate limits; corporate proxies intercepting registry traffic; pulling a GoVersion tag that was never published; flaky VPN/DNS.
Related errors
- ensuring image availability: %w
- reading pull output: %w
- DERPer is not ready: %w
- listing updated clients: %w
- creating or getting network: %w
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/1d85113e0a388ef8.
Report an issue: GitHub.