{"record":{"id":"e9d6e3b9cf55ee5d","repo":"argoproj/argo-workflows","slug":"not-found","errorCode":null,"errorMessage":"Not Found","messagePattern":"Not Found","errorType":"http","errorClass":null,"httpStatus":404,"severity":"warning","filePath":"server/artifacts/artifact_server.go","lineNumber":140,"sourceCode":"\tallowed, err = auth.CanI(ctx, \"create\", \"workflows\", namespace, \"\")\n\tif err != nil {\n\t\ta.serverInternalError(ctx, err, w)\n\t\treturn\n\t}\n\tif !allowed {\n\t\thttp.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)\n\t\treturn\n\t}\n\n\t// Get WorkflowTemplate to find artifact configuration\n\twfClient := auth.GetWfClient(ctx)\n\twfTemplate, err := wfClient.ArgoprojV1alpha1().WorkflowTemplates(namespace).Get(ctx, workflowTemplateName, metav1.GetOptions{})\n\tif err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"Failed to get WorkflowTemplate %s/%s: %v\", namespace, workflowTemplateName, err), http.StatusNotFound)\n\t\treturn\n\t}\n\tif validateErr := a.instanceIDService.Validate(wfTemplate); validateErr != nil {\n\t\thttp.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)\n\t\treturn\n\t}\n\n\t// Enforce a hard cap on the total request body size before buffering any\n\t// of it, so a caller cannot exhaust server disk/memory with an oversized upload.\n\tmaxUploadBytes, err := env.GetInt(\"ARGO_SERVER_MAX_ARTIFACT_UPLOAD_BYTES\", 1<<30)\n\tif err != nil {\n\t\ta.serverInternalError(ctx, err, w)\n\t\treturn\n\t}\n\tr.Body = http.MaxBytesReader(w, r.Body, int64(maxUploadBytes))\n\n\t// mime/multipart.ReadForm already removes temp files on parse error, but\n\t// registering cleanup here makes the handler's correctness independent of\n\t// that stdlib internal — any future error return still frees temp files.\n\tdefer func() {\n\t\tif r.MultipartForm != nil {\n\t\t\t_ = r.MultipartForm.RemoveAll()","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/server/artifacts/artifact_server.go#L122-L158","documentation":"After a successful GET, the server validates the template against the configured instanceID via instanceIDService.Validate. On mismatch it intentionally returns a generic 404 'Not Found' without details, so outside callers cannot probe which templates exist in an instance. It looks identical to a missing template but the template actually exists.","triggerScenarios":"ARGO_INSTANCEID (controller instanceID) is set but the WorkflowTemplate lacks the matching instanceID label/annotation (or vice versa) — validation fails and the handler masks it as 404.","commonSituations":"Multi-instance clusters (staging/prod controllers sharing a cluster) where templates were created before instanceID was configured or copied between namespaces without the label.","solutions":["Check the controller's instanceID setting in the workflow-controller configmap","Add the matching instanceID to the WorkflowTemplate metadata (or re-apply templates via the same instance's tooling)","Temporarily check argo-server logs to confirm the 404 is from instanceID validation rather than a missing object","If no multi-instance setup is intended, unset instanceID so validation passes for unlabeled templates"],"exampleFix":"# before\ncurl .../upload-artifacts/default/my-tmpl/art   # template exists, no instanceID label\n# after\nmetadata:\n  labels:\n    workflows.argoproj.io/instance-id: my-instance  # match controller instanceID","handlingStrategy":"validation","validationCode":"tpl=$(kubectl get workflowtemplate <name> -n <ns> -o jsonpath='{.metadata.labels.workflows\\.argoproj\\.io/instance-id}')\nctrl=$(kubectl -n argo get cm workflow-controller-configmap -o yaml | grep instanceID)\n[ \"$tpl\" = \"${ctrl##*: }\" ] || echo \"instanceID mismatch\"","typeGuard":null,"tryCatchPattern":"if resp.StatusCode == 404 && templateExistsInCluster {\n    // likely instanceID validation masking — compare labels vs controller config\n}","preventionTips":["Keep instanceID unset unless running multi-instance controllers","Apply templates through tooling that injects the correct instanceID automatically","When copying templates across namespaces/instances, re-add the instance-id label"],"tags":["http-404","instanceid","multi-tenancy","kubernetes"],"backgroundTag":"instanceid-mismatch","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"}