hashicorp/terraform · error
storage.NewClient() failed
Error message
storage.NewClient() failed: %v
What it means
Thrown when the Google Cloud Storage client constructor returns an error. By this point credential options, user agent, and any custom endpoint have been assembled into opts; storage.NewClient(ctx, opts...) failing means authentication, transport, or endpoint configuration is invalid.
Solutions
- Run `gcloud auth application-default login` (or set GOOGLE_APPLICATION_CREDENTIALS) and retry.
- Inspect the wrapped %v error in the message — it names the real cause (e.g., 'cannot find credentials').
- Remove or correct storage_custom_endpoint if it points at a non-GCS service.
- Verify outbound network access to oauth2.googleapis.com and storage.googleapis.com.
Example fix
// before — no credentials in CI // after gcloud auth application-default login --backend=no # or set GOOGLE_APPLICATION_CREDENTIALS
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight ADC check before invoking terraform. // `gcloud auth application-default print-access-token` returns non-zero if ADC is missing.
Try / catch
// Retry transient client-creation failures with backoff.
var client *storage.Client
var err error
for i := 0; i < 3; i++ {
client, err = storage.NewClient(ctx, opts...)
if err == nil { break }
if isPermAuthErr(err) { break } // don't retry bad creds
time.Sleep(backoff(i))
} Prevention
- Run `gcloud auth application-default login` in interactive environments.
- In CI, set GOOGLE_APPLICATION_CREDENTIALS or enable Workload Identity.
- Inspect the wrapped error first — do not retry on auth-config errors.
When it happens
Trigger: storage.NewClient returns a non-nil error — invalid credentials JSON format accepted earlier but rejected by the token endpoint, no application-default credentials available, unreachable custom endpoint, or system clock skew breaking the OAuth exchange.
Common situations: Running terraform in CI without GOOGLE_APPLICATION_CREDENTIALS or workload identity; pointing storage_custom_endpoint at a URL that returns non-OAuth responses; the ADC metadata server is unreachable from the VM; transient network failure reaching googleapis.com.
Related errors
- Failed to read state file from
- Error loading credentials
- Failed to delete state file
- Failed to open state file at
- Failed to read state file attrs from
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/f0327ea735258656.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/gcs/backend.go:256
}
opts = append(opts, option.WithTokenSource(ts))
} else {
opts = append(opts, credOptions...)
}
opts = append(opts, option.WithUserAgent(httpclient.UserAgentString()))
// Custom endpoint for storage API
if storageEndpoint := data.String("storage_custom_endpoint"); storageEndpoint != "" {
endpoint := option.WithEndpoint(storageEndpoint)
opts = append(opts, endpoint)
}
client, err := storage.NewClient(ctx, opts...)
if err != nil {
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("storage.NewClient() failed: %v", err),
)
}
b.storageClient = client
// Customer-supplied encryption
key := data.String("encryption_key")
if key != "" {
kc, err := readPathOrContents(key)
if err != nil {
return backendbase.ErrorAsDiagnostics(
fmt.Errorf("Error loading encryption key: %s", err),
)
}
// The GCS client expects a customer supplied encryption key to be
// passed in as a 32 byte long byte slice. The byte slice is base64
// encoded before being passed to the API. We take a base64 encoded keyView on GitHub (pinned to d32a084675)