{"record":{"id":"197f6e1940fcdf83","repo":"vxcontrol/pentagi","slug":"image-download-stream-processing-failed-w","errorCode":null,"errorMessage":"image download stream processing failed: %w","messagePattern":"image download stream processing failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/docker/client.go","lineNumber":1195,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to list images: %w\", err)\n\t}\n\n\tif imageExistsLocally := len(images.Items) > 0; imageExistsLocally {\n\t\treturn nil\n\t}\n\n\tdc.logger.WithContext(ctx).WithField(\"image\", imageName).Info(\"initiating image download from registry...\")\n\n\tpullStream, err := dc.client.ImagePull(ctx, imageName, client.ImagePullOptions{})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to pull image: %w\", err)\n\t}\n\tdefer pullStream.Close()\n\n\t// drain pull stream to completion\n\tif _, err := io.Copy(io.Discard, pullStream); err != nil {\n\t\treturn fmt.Errorf(\"image download stream processing failed: %w\", err)\n\t}\n\n\tdc.logger.WithContext(ctx).WithField(\"image\", imageName).Debug(\"image pull completed\")\n\n\treturn nil\n}\n\nfunc getHostDockerSocket(ctx context.Context, cli *client.Client) string {\n\tdaemonHost := strings.TrimPrefix(cli.DaemonHost(), \"unix://\")\n\tif info, err := os.Stat(daemonHost); err != nil || info.IsDir() {\n\t\treturn defaultDockerSocketPath\n\t}\n\n\thostname, err := os.Hostname()\n\tif err != nil {\n\t\treturn daemonHost\n\t}\n","sourceCodeStart":1177,"sourceCodeEnd":1213,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/docker/client.go#L1177-L1213","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nctx, cancel := context.WithTimeout(ctx, 30*time.Second)\n// after\nctx, cancel := context.WithTimeout(ctx, 10*time.Minute) // allow large image pulls","handlingStrategy":"retry","validationCode":"null","typeGuard":"func isPullStreamError(err error) bool { return strings.Contains(err.Error(), \"image download stream processing failed\") }","tryCatchPattern":"err := dc.pullImage(ctx, imageName)\nif err != nil && strings.Contains(err.Error(), \"image download stream processing failed\") {\n    // layers are cached; a retry resumes cheaply\n    err = retry.Do(func() error { return dc.pullImage(ctx, imageName) }, retry.Attempts(3))\n}","preventionTips":["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"],"tags":["docker","io","network","timeout"],"backgroundTag":"docker-pull-stream-interrupted","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}