{"record":{"id":"f0327ea735258656","repo":"hashicorp/terraform","slug":"storage-newclient-failed-v","errorCode":null,"errorMessage":"storage.NewClient() failed: %v","messagePattern":"storage\\.NewClient\\(\\) failed: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/backend/remote-state/gcs/backend.go","lineNumber":256,"sourceCode":"\t\t}\n\n\t\topts = append(opts, option.WithTokenSource(ts))\n\n\t} else {\n\t\topts = append(opts, credOptions...)\n\t}\n\n\topts = append(opts, option.WithUserAgent(httpclient.UserAgentString()))\n\n\t// Custom endpoint for storage API\n\tif storageEndpoint := data.String(\"storage_custom_endpoint\"); storageEndpoint != \"\" {\n\t\tendpoint := option.WithEndpoint(storageEndpoint)\n\t\topts = append(opts, endpoint)\n\t}\n\tclient, err := storage.NewClient(ctx, opts...)\n\tif err != nil {\n\t\treturn backendbase.ErrorAsDiagnostics(\n\t\t\tfmt.Errorf(\"storage.NewClient() failed: %v\", err),\n\t\t)\n\t}\n\n\tb.storageClient = client\n\n\t// Customer-supplied encryption\n\tkey := data.String(\"encryption_key\")\n\tif key != \"\" {\n\t\tkc, err := readPathOrContents(key)\n\t\tif err != nil {\n\t\t\treturn backendbase.ErrorAsDiagnostics(\n\t\t\t\tfmt.Errorf(\"Error loading encryption key: %s\", err),\n\t\t\t)\n\t\t}\n\n\t\t// The GCS client expects a customer supplied encryption key to be\n\t\t// passed in as a 32 byte long byte slice. The byte slice is base64\n\t\t// encoded before being passed to the API. We take a base64 encoded key","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/gcs/backend.go#L238-L274","documentation":"Wraps the error returned by cloud.google.com/go/storage.NewClient during backend Configure(). NewClient builds the underlying HTTP transport and resolves the token source (credentials JSON, access token, impersonated token, or Application Default Credentials); any failure there is surfaced verbatim in the %v slot. This is the catch-all for auth, transport, and endpoint construction problems before any object request is made.","triggerScenarios":"Configure() reaches storage.NewClient with: invalid/revoked credentials JSON, an expired access_token, an impersonate_service_account that the caller lacks 'iam.serviceAccounts.generateAccessToken' on, GOOGLE_APPLICATION_CREDENTIALS pointing at a missing file, no network, or an unreachable storage_custom_endpoint.","commonSituations":"CI runners without GCP workload identity / ADC set up; a service-account JSON key that was rotated; impersonation target without the Service Account Token Creator role; air-gapped environment; GOOGLE_STORAGE_CUSTOM_ENDPOINT typo'd to a host that refuses connections.","solutions":["Run 'gcloud auth application-default login' (or set GOOGLE_APPLICATION_CREDENTIALS / GOOGLE_CREDENTIALS to a valid key file) and retry 'terraform init'.","If using impersonation, grant the calling identity 'roles/iam.serviceAccountTokenCreator' on the target SA; verify with 'gcloud iam service-accounts get-access-token'.","Inspect the %v detail: a 401/403 means credentials/scopes, a dial error means network/endpoint; fix the matching cause.","If storage_custom_endpoint is set, confirm the URL is reachable and returns the Storage JSON API shape."],"exampleFix":"// before (env)\nGOOGLE_CREDENTIALS=$(cat /etc/secrets/key.json)   # key was rotated\n\n// after\nexport GOOGLE_APPLICATION_CREDENTIALS=/etc/secrets/current-key.json\ngcloud auth application-default-login   # or WIF for CI\nterraform init","handlingStrategy":"try-catch","validationCode":"// Pre-flight credential check before terraform init\nimport \"cloud.google.com/go/storage\"\nfunc canCreateStorageClient(ctx context.Context) error {\n    c, err := storage.NewClient(ctx)\n    if err != nil { return err }\n    c.Close()\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if diags := backend.Configure(configVal); diags.HasErrors() {\n    for _, d := range diags {\n        if strings.Contains(d.Description().Summary, \"storage.NewClient() failed\") {\n            // surface auth/network remediation hints, attempt ADC refresh, or abort\n        }\n    }\n}","preventionTips":["Pin GOOGLE_APPLICATION_CREDENTIALS to a known-good key file in CI.","Use Workload Identity Federation instead of long-lived keys to avoid rotation breakage.","For impersonation, grant Service Account Token Creator on the target.","Test storage.NewClient in isolation when refactoring credentials."],"tags":["gcs","gcp","auth","adc","credentials","impersonation","network"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}