vxcontrol/pentagi · error

failed to pull image: %w

Error message

failed to pull image: %w

What it means

Returned by the Docker client's image pull helper when the initial call to the Docker daemon's ImagePull API fails. The underlying registry/daemon error (auth failure, missing tag, network problem) is wrapped via %w so errors.Is/As still work against the original cause.

Source

Thrown at backend/pkg/docker/client.go:1189

func (dc *dockerClient) pullImage(ctx context.Context, imageName string) error {
	filterArgs := make(client.Filters).Add("reference", imageName)
	images, err := dc.client.ImageList(ctx, client.ImageListOptions{
		Filters: filterArgs,
	})
	if err != nil {
		return fmt.Errorf("failed to list images: %w", err)
	}

	if imageExistsLocally := len(images.Items) > 0; imageExistsLocally {
		return nil
	}

	dc.logger.WithContext(ctx).WithField("image", imageName).Info("initiating image download from registry...")

	pullStream, err := dc.client.ImagePull(ctx, imageName, client.ImagePullOptions{})
	if err != nil {
		return fmt.Errorf("failed to pull image: %w", err)
	}
	defer pullStream.Close()

	// drain pull stream to completion
	if _, err := io.Copy(io.Discard, pullStream); err != nil {
		return fmt.Errorf("image download stream processing failed: %w", err)
	}

	dc.logger.WithContext(ctx).WithField("image", imageName).Debug("image pull completed")

	return nil
}

func getHostDockerSocket(ctx context.Context, cli *client.Client) string {
	daemonHost := strings.TrimPrefix(cli.DaemonHost(), "unix://")
	if info, err := os.Stat(daemonHost); err != nil || info.IsDir() {
		return defaultDockerSocketPath
	}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Verify the image name and tag are correct and that the image exists in the registry
  2. Check that registry credentials are available (docker login / auth config passed to ImagePullOptions)
  3. Confirm the Docker daemon is running: `docker info`; restart it if needed
  4. Test registry connectivity from the host (`docker pull <image>` manually)
  5. Inspect the wrapped cause with errors.Is/As to see the exact daemon error

Example fix

// before
dc.client.ImagePull(ctx, imageName, client.ImagePullOptions{})
// after
opts := client.ImagePullOptions{}
if user != "" {
    opts.RegistryAuth = encodeRegistryAuth(user, pass, registryHost)
}
pullStream, err := dc.client.ImagePull(ctx, imageName, opts)
Defensive patterns

Strategy: try-catch

Validate before calling

if err := validateImageName(imageName); err != nil { return err } // non-empty, has tag, registry reachable
if !dockerDaemonReachable() { return errors.New("docker daemon unavailable") }

Type guard

func isImagePullError(err error) bool { return strings.Contains(err.Error(), "failed to pull image") }

Try / catch

if err := dc.pullImage(ctx, imageName); err != nil {
    var netErr net.Error
    switch {
    case errors.Is(err, context.DeadlineExceeded):
        // retry with longer timeout
    case errors.As(err, &netErr):
        // check daemon/registry connectivity
    default:
        log.WithError(err).Error("image pull failed")
    }
}

Prevention

When it happens

Trigger: Calling the pull-image code path with an image name that does not exist in the registry, with bad/missing registry credentials, when the Docker daemon is unreachable, or when the registry is unreachable.

Common situations: Typo in image name or tag; image exists only in a private registry; `docker login` credentials not configured for the daemon host; Docker daemon stopped; corporate proxy/firewall blocking registry; DNS failure in the container host.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/29cd546a1f25f4e4. Report an issue: GitHub.