{"record":{"id":"382eb43e24cbdb51","repo":"argoproj/argo-workflows","slug":"failed-to-stream-artifact-v","errorCode":null,"errorMessage":"failed to stream artifact: %v","messagePattern":"failed to stream artifact: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"server/artifacts/artifact_server.go","lineNumber":780,"sourceCode":"\t\treturn err\n\t}\n\n\tdefer func() {\n\t\tif closeErr := stream.Close(); closeErr != nil {\n\t\t\tlogger.WithError(closeErr).WithField(\"stream\", stream).Warn(ctx, \"Error closing stream\")\n\t\t}\n\t}()\n\n\tkey, _ := art.GetKey()\n\tw.Header().Add(\"Content-Disposition\", fmt.Sprintf(`filename=\"%s\"`, path.Base(key)))\n\tw.Header().Add(\"Content-Type\", mime.TypeByExtension(path.Ext(key)))\n\ta.setSecurityHeaders(w)\n\n\t_, err = io.Copy(w, stream)\n\tif err != nil {\n\t\terrStr := fmt.Sprintf(\"failed to stream artifact: %v\", err)\n\t\thttp.Error(w, errStr, http.StatusInternalServerError)\n\t\treturn errors.New(errStr)\n\t}\n\tw.WriteHeader(http.StatusOK)\n\treturn nil\n}\n\nfunc (a *ArtifactServer) getWorkflowAndValidate(ctx context.Context, namespace string, workflowName string) (*wfv1.Workflow, error) {\n\twfClient := auth.GetWfClient(ctx)\n\twf, err := wfClient.ArgoprojV1alpha1().Workflows(namespace).Get(ctx, workflowName, metav1.GetOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = a.instanceIDService.Validate(wf)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = a.hydrator.Hydrate(ctx, wf)\n\tif err != nil {\n\t\treturn nil, err","sourceCodeStart":762,"sourceCodeEnd":798,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/server/artifacts/artifact_server.go#L762-L798","documentation":"returnArtifact streams an artifact to the HTTP response; if io.Copy fails while writing the artifact bytes to the client, it writes a 500 and returns this error. Causes are typically client disconnects or I/O problems writing the response body.","triggerScenarios":"GET artifact endpoints (getArtifact, GetArtifactFile, getArtifactByUID via the artifact server) where the copy from the opened stream to the http.ResponseWriter fails — client closed the connection mid-download, network interruption, or the underlying stream reader errored after headers were being written.","commonSituations":"Browsers/users cancelling large artifact downloads; proxy or ingress timeouts killing long transfers; flaky network between client and argo-server; UI fetching artifact logs while navigating away.","solutions":["Retry the download from the UI/CLI — transient disconnects are the most common cause.","Check ingress/proxy timeout settings (e.g. nginx proxy-read-timeout) for large artifacts and raise them.","Inspect argo-server logs for the wrapped %v cause to distinguish client-cancel vs server I/O errors.","Verify network stability / reduce artifact size if transfers keep failing mid-stream."],"exampleFix":"// client-side retry pattern (Go)\n// before\nresp, err := http.Get(url)\n// after\nvar resp *http.Response\nfor i := 0; i < 3 && err != nil; i++ {\n    resp, err = http.Get(url)\n}\nif err != nil { return fmt.Errorf(\"download failed after retries: %w\", err) }","handlingStrategy":"retry","validationCode":"// preflight: ensure artifact exists and is fetchable\nresp, err := http.Head(artifactURL)\nif err != nil || resp.StatusCode != http.StatusOK {\n    return fmt.Errorf(\"artifact not ready: status %v\", resp.StatusCode)\n}","typeGuard":null,"tryCatchPattern":"resp, err := http.Get(artifactURL)\nif err != nil || strings.Contains(errBody, \"failed to stream artifact\") {\n    // backoff and retry the download\n    time.Sleep(2*time.Second)\n    resp, err = http.Get(artifactURL)\n}","preventionTips":["Retry transient download failures with backoff","Raise ingress/proxy timeouts for large artifacts","Avoid cancelling UI requests that stream artifacts","Check argo-server logs for the underlying io.Copy cause"],"tags":["http","artifacts","streaming","network"],"backgroundTag":"artifact-stream-failed","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}