{"record":{"id":"b05a3f9c9b1c4044","repo":"argoproj/argo-workflows","slug":"s-s","errorCode":null,"errorMessage":"%s: %s","messagePattern":"%s: %s","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/util/plugin/plugin.go","lineNumber":93,"sourceCode":"\t\tcase http.StatusOK:\n\t\t\treturn json.NewDecoder(resp.Body).Decode(reply)\n\t\tcase http.StatusNotFound:\n\t\t\tlog.Info(ctx, \"method not found, not calling again\")\n\t\t\tp.invalid[method] = true\n\t\t\t_, err := io.Copy(io.Discard, resp.Body)\n\t\t\treturn err\n\t\tcase http.StatusServiceUnavailable:\n\t\t\tdata, err := io.ReadAll(resp.Body)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn errors.NewErrTransient(string(data))\n\t\tdefault:\n\t\t\tdata, err := io.ReadAll(resp.Body)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"%s: %s\", resp.Status, string(data))\n\t\t}\n\t})\n}\n","sourceCodeStart":75,"sourceCodeEnd":97,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/util/plugin/plugin.go#L75-L97","documentation":"A plugin HTTP call received a response with an unexpected status code (not 2xx and not the handled transient status). The plugin executor surfaces the HTTP status line plus the raw response body as the error, e.g. '500 Internal Server Error: <body>'. It tells you the plugin's own HTTP endpoint rejected the request.","triggerScenarios":"workflow/executor/plugin driver posts a request to a plugin's HTTP endpoint and the response status falls into the default switch case — any non-handled status (e.g. 400, 403, 404, 500) — and the status+body are wrapped via fmt.Errorf(\"%s: %s\", resp.Status, data).","commonSituations":"Plugin service not deployed/misconfigured (404), plugin auth failing (401/403), plugin crashing on the request (500), wrong port/URL in the plugin config; non-2xx statuses other than the recognized transient one.","solutions":["Read the body in the error message — it usually contains the plugin's own error explaining the failure","Verify the plugin endpoint URL/port in the plugin ConfigMap matches the running plugin service","Check the plugin's logs for the corresponding request failure and fix server-side (auth, crash, bad payload)","If the status indicates a transient condition in your plugin, return the recognized transient status so Argo retries"],"exampleFix":"// before (plugin handler returns bare 500)\nw.WriteHeader(500)\n// after (actionable body)\nhttp.Error(w, \"executor plugin: failed to load template: missing arg\", 500)","handlingStrategy":"retry","validationCode":"// preflight: check the plugin endpoint is reachable\nresp, err := http.Get(pluginURL + \"/health\")\nif err != nil || resp.StatusCode != 200 {\n    return fmt.Errorf(\"plugin endpoint %s unhealthy\", pluginURL)\n}","typeGuard":null,"tryCatchPattern":"err := executor.CallPlugin(ctx, ...)\nif err != nil {\n    var statusErr interface{ HTTPStatus() int }\n    if strings.Contains(err.Error(), \": \") && !util_errors.IsTransientErr(ctx, err) {\n        // non-transient HTTP failure: check plugin logs, do not retry blindly\n    }\n}","preventionTips":["Monitor plugin service health and logs alongside the workflow controller","Pin plugin versions and verify endpoint URLs after config changes","Return recognizable transient statuses from the plugin for retryable conditions"],"tags":["http","plugin","executor","network"],"backgroundTag":"http-error-response","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"}