{"record":{"id":"625b075aee56615d","repo":"argoproj/argo-workflows","slug":"gcs-storage-newclient-with-credential-w","errorCode":null,"errorMessage":"GCS storage.NewClient with credential: %w","messagePattern":"GCS storage\\.NewClient with credential: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/artifacts/gcs/gcs.go","lineNumber":90,"sourceCode":"\treturn false\n}\n\nfunc (h *ArtifactDriver) newGCSClient(ctx context.Context) (*storage.Client, error) {\n\tif h.ServiceAccountKey != \"\" {\n\t\treturn newGCSClientWithCredential(ctx, h.ServiceAccountKey)\n\t}\n\t// Assume it uses Workload Identity\n\treturn newGCSClientDefault(ctx)\n}\n\nfunc newGCSClientWithCredential(ctx context.Context, serviceAccountJSON string) (*storage.Client, error) {\n\tcreds, err := google.CredentialsFromJSONWithType(ctx, []byte(serviceAccountJSON), google.ServiceAccount, storage.ScopeReadWrite)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GCS client CredentialsFromJSONWithType: %w\", err)\n\t}\n\tclient, err := storage.NewClient(ctx, option.WithCredentials(creds))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GCS storage.NewClient with credential: %w\", err)\n\t}\n\treturn client, nil\n}\n\nfunc newGCSClientDefault(ctx context.Context) (*storage.Client, error) {\n\tclient, err := storage.NewClient(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GCS storage.NewClient: %w\", err)\n\t}\n\treturn client, nil\n}\n\n// Load function downloads objects from GCS\nfunc (h *ArtifactDriver) Load(ctx context.Context, inputArtifact *wfv1.Artifact, path string) error {\n\terr := waitutil.Backoff(defaultRetry,\n\t\tfunc() (bool, error) {\n\t\t\tkey := filepath.Clean(inputArtifact.GCS.Key)\n\t\t\tlogger := logging.RequireLoggerFromContext(ctx)","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/artifacts/gcs/gcs.go#L72-L108","documentation":"After credentials parse successfully, newGCSClientWithCredential calls storage.NewClient with those credentials. This error wraps a failure constructing the Cloud Storage client. Because option.WithCredentials is used, failures here usually come from credential fields the client cannot use (e.g. malformed key data that parses but lacks valid fields) or client-option/environment conflicts.","triggerScenarios":"storage.NewClient(ctx, option.WithCredentials(creds)) failing — typically when the service-account JSON parsed but has invalid internal fields, or when environment variables like STORAGE_EMULATOR_HOST or GOOGLE_API_USE_MTLS_ENDPOINT produce an incompatible client configuration.","commonSituations":"Corrupted/partially rotated key; inconsistent GOOGLE_APPLICATION_CREDENTIALS and explicit creds mix; mTLS endpoint misconfiguration in restricted networks; broken STORAGE_EMULATOR_HOST setting in the executor environment.","solutions":["Re-download a fresh service-account key and update the secret","Unset conflicting env vars (GOOGLE_APPLICATION_CREDENTIALS, STORAGE_EMULATOR_HOST) in the workflow/executor pod","Retry with newGCSClientDefault (no explicit creds) if workload identity is configured","Check the storage client library version for known issues and upgrade the argo image"],"exampleFix":"// before\nkubectl create secret generic gcs-creds --from-file=serviceAccountKey=partially-truncated-key.json\n// after\nkubectl delete secret gcs-creds\nkubectl create secret generic gcs-creds --from-file=serviceAccountKey=key.json","handlingStrategy":"validation","validationCode":"// ensure the executor env has no conflicting client options:\n// env:\n// - name: STORAGE_EMULATOR_HOST\n//   value: \"\"   # must not point at a dead emulator\n// and validate the key fields after CredentialsFromJSON:\nif creds == nil || creds.ProjectID == \"\" { /* key lacks project_id; regenerate */ }","typeGuard":null,"tryCatchPattern":"_, err := newGCSClient(ctx, keyJSON)\nif err != nil {\n\tif strings.Contains(err.Error(), \"storage.NewClient with credential\") {\n\t\t// fall back to default ADC client\n\t\tclient, derr := storage.NewClient(ctx)\n\t\tif derr == nil { return use(client) }\n\t}\n\treturn err\n}","preventionTips":["Regenerate keys after rotation; old keys stop working silently","Avoid mixing GOOGLE_APPLICATION_CREDENTIALS with explicit WithCredentials options","Pin/upgrade the cloud.google.com/go/storage dependency with the argo release"],"tags":["gcs","gcp","credentials","client-init"],"backgroundTag":"gcs-client-init-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"}