hashicorp/terraform · error
failed to retrieve credentials for %s: %s
Error message
failed to retrieve credentials for %s: %s
What it means
Returned by RegistrySource.registryClient (internal/getproviders/registry_source.go:144) when the credentials lookup for a registry hostname fails. The host has been discovered successfully and the providers.v1 service URL resolved, but calling s.services.CredentialsForHost(hostname) returned a non-nil error, meaning a configured credentials helper (or built-in credentials source) errored rather than producing a token. The message passes through the helper's own error verbatim as the second %s.
Source
Thrown at internal/getproviders/registry_source.go:144
case *disco.ErrVersionNotSupported:
return nil, ErrHostNoProviders{
Hostname: hostname,
HasOtherVersion: true,
}
default:
return nil, ErrHostUnreachable{
Hostname: hostname,
Wrapped: err,
}
}
// Check if we have credentials configured for this hostname.
creds, err := s.services.CredentialsForHost(hostname)
if err != nil {
// This indicates that a credentials helper failed, which means we
// can't do anything better than just pass through the helper's
// own error message.
return nil, fmt.Errorf("failed to retrieve credentials for %s: %s", hostname, err)
}
return newRegistryClient(url, creds), nil
}
func (s *RegistrySource) ForDisplay(provider addrs.Provider) string {
return fmt.Sprintf("registry %s", provider.Hostname.ForDisplay())
}
View on GitHub (pinned to c9def3e214)
Solutions
- Read the trailing helper error (%s) verbatim first; it identifies the failing credentials source.
- Verify the credentials_helper executable in ~/.terraformrc exists, is executable, and is on PATH; run it manually with the get/getenv action to reproduce.
- If using a private registry, set a token via TF_TOKEN_<hostname> env var or terraform login <hostname> for the affected host.
- Check file permissions on ~/.terraform.d/ and any token files; ensure the helper process can read them.
- For CI, ensure the same credentials source available locally is provisioned (env vars / helper binary) in the runner.
Example fix
// before (~/.terraformrc)
credentials_helper "tfe" { args = ["/wrong/path/helper"] }
// terraform init -> failed to retrieve credentials for app.terraform.io: exec: ...: no such file
// after
credentials_helper "tfe" { args = ["/usr/local/bin/credential-helper"] }
// or bypass helper:
export TF_TOKEN_app.terraform.io=<token> Defensive patterns
Strategy: try-catch
Validate before calling
// Before constructing the source, probe the credentials helper:
func credentialsAvailable(services *disco.Disco, hostname svchost.Hostname) error {
host, err := services.Discover(hostname)
if err != nil { return err }
if _, err := host.ServiceURL("providers.v1"); err != nil { return err }
// CredentialsForHost is the call that fails at line 144
if _, err := services.CredentialsForHost(hostname); err != nil {
return fmt.Errorf("credentials for %s unavailable: %w", hostname, err)
}
return nil
} Try / catch
// Treat registry/credential failures as retryable-or-fixable, surface the helper error:
versions, _, err := src.AvailableVersions(ctx, provider)
if err != nil {
if strings.Contains(err.Error(), "failed to retrieve credentials for") {
return fmt.Errorf("fix credentials for %s: %w", provider.Hostname, err)
}
return err
} Prevention
- Prefer TF_TOKEN_<hostname> env vars over helper plugins in CI for fewer moving parts.
- Smoke-test the credentials_helper binary in isolation before terraform init.
- Pin the helper version and store its config in version control.
- Log hostname + helper error together so the failing host is obvious.
When it happens
Trigger: A terraform init / provider download against a private/alternative registry hostname whose credentials helper plugin (defined in ~/.terraformrc cli_credentials CustomCommand) exits non-zero, returns malformed output, or cannot run; or a host where the credentials source is configured but the underlying token store (e.g. an expired OAuth/credential file) is unreadable.
Common situations: Misconfigured credentials_helper executable path, helper binary not on PATH, helper returning invalid JSON, expired tokens, permission errors reading ~/.terraform.d/credentials, or switching to a Terraform Enterprise/private registry without provisioning credentials. Also appears in CI where the helper is absent but hostname expects auth.
Related errors
- error when obtaining provider instance during state store in
- Error loading state: %[2]s Terraform failed to load the
- Error parsing provider ID from Registry: %s
- Registry returned provider with type %q, expected %q
- Attempted to initialize pluggable state with a nil provider
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/0a0ae45e23f8b0ac.
Report an issue: GitHub.