vxcontrol/pentagi · error
image download stream processing failed: %w
Error message
image download stream processing failed: %w
What it means
Returned when the ImagePull API call succeeded but draining the pull progress stream (io.Copy to io.Discard) failed mid-transfer. This indicates the pull was interrupted — the stream from the daemon broke before the pull finished.
Source
Thrown at backend/pkg/docker/client.go:1195
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
}
hostname, err := os.Hostname()
if err != nil {
return daemonHost
}
View on GitHub (pinned to ea665308ba)
Solutions
- Increase the context timeout or remove the deadline for large image pulls
- Retry the pull — completed layers are cached and resume is cheap
- Check daemon logs and host network stability for mid-stream disconnects
- Check whether the caller cancels the ctx unexpectedly
- Pull the image manually on the host to warm the cache before running the flow
Example fix
// before ctx, cancel := context.WithTimeout(ctx, 30*time.Second) // after ctx, cancel := context.WithTimeout(ctx, 10*time.Minute) // allow large image pulls
Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
func isPullStreamError(err error) bool { return strings.Contains(err.Error(), "image download stream processing failed") } Try / catch
err := dc.pullImage(ctx, imageName)
if err != nil && strings.Contains(err.Error(), "image download stream processing failed") {
// layers are cached; a retry resumes cheaply
err = retry.Do(func() error { return dc.pullImage(ctx, imageName) }, retry.Attempts(3))
} Prevention
- Use generous timeouts sized for the largest expected image
- Avoid cancelling contexts mid-pull; tie ctx lifetime to the pull operation
- Warm the image cache on hosts before running flows
- Monitor network stability between the daemon host and the registry
When it happens
Trigger: io.Copy on the pull stream returns an error: connection to the Docker daemon dropped mid-pull, context deadline/cancellation fires while the pull is in progress, or the daemon closes the stream abnormally.
Common situations: Slow/unstable network pulling large images combined with a short context timeout; caller cancels the context; daemon restart during a long pull; proxy terminating long-lived connections.
Related errors
- failed to read response body: %w
- failed to copy output: %w
- failed to ensure docker network %s: %w
- failed to pull default image '%s': %w
- truncated exec stream: %w
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/197f6e1940fcdf83.
Report an issue: GitHub.