{"record":{"id":"e12f9abd06de79b7","repo":"hyperledger/fabric","slug":"failed-to-wait-pull-s-s","errorCode":null,"errorMessage":"Failed to wait pull %s: %s","messagePattern":"Failed to wait pull (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/platforms/util/utils.go","lineNumber":85,"sourceCode":"\t\t}\n\t}\n\n\tlogger.Debugf(\"Attempting build with options: %s\", opts)\n\n\t// -----------------------------------------------------------------------------------\n\t// Ensure the image exists locally, or pull it from a registry if it doesn't\n\t// -----------------------------------------------------------------------------------\n\t_, err := client.ImageInspect(context.Background(), opts.Image)\n\tif err != nil {\n\t\tlogger.Debugf(\"Image %s does not exist locally, attempt pull\", opts.Image)\n\n\t\tipResp, err := client.ImagePull(context.Background(), opts.Image, dcli.ImagePullOptions{})\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Failed to pull %s: %s\", opts.Image, err)\n\t\t}\n\t\terr = ipResp.Wait(context.Background())\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Failed to wait pull %s: %s\", opts.Image, err)\n\t\t}\n\t}\n\n\t// -----------------------------------------------------------------------------------\n\t// Create an ephemeral container, armed with our Image/Cmd\n\t// -----------------------------------------------------------------------------------\n\tcontainer, err := client.ContainerCreate(context.Background(), dcli.ContainerCreateOptions{\n\t\tConfig: &dcontainer.Config{\n\t\t\tAttachStdout: true,\n\t\t\tAttachStderr: true,\n\t\t\tEnv:          opts.Env,\n\t\t\tCmd:          []string{\"/bin/sh\", \"-c\", opts.Cmd},\n\t\t\tImage:        opts.Image,\n\t\t},\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Error creating container: %s\", err)\n\t}","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/platforms/util/utils.go#L67-L103","documentation":"After ImagePull succeeds, DockerBuild waits for the pull response stream to finish via ipResp.Wait. This error means the pull started but did not complete successfully — the stream ended with an error (e.g. manifest/layer failure or context cancellation). The builder image may be partially pulled or missing.","triggerScenarios":"client.ImagePull succeeds initially but ipResp.Wait(context) returns an error during layer download/extraction, or the context is cancelled/times out mid-pull.","commonSituations":"Flaky networks interrupting large layer downloads, registry returning errors mid-stream, or callers passing short-lived contexts that expire during the pull.","solutions":["Retry the operation; transient layer download failures often resolve","Use a context with an adequate timeout (or context.Background) for the pull","Verify disk space on the docker host for layer extraction","Pre-pull the image manually with docker pull to stabilize"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)\ndefer cancel()\n// pass this ctx to DockerBuild-dependent calls so the pull can complete","typeGuard":null,"tryCatchPattern":"if err != nil && strings.HasPrefix(err.Error(), \"Failed to wait pull\") {\n    // pull started but failed mid-stream: retry with longer timeout\n    return retryWithBackoff(func() error { return util.DockerBuild(opts, client) }, 3)\n}","preventionTips":["Use long-lived contexts for image pulls on slow networks","Pre-pull images out-of-band to avoid mid-stream failures","Ensure adequate disk space for layer extraction","Retry transient pull failures with exponential backoff"],"tags":["docker","image-pull","network","timeout"],"backgroundTag":"image-pull-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}