Terraform Error: '401 Unauthorized' from the Remote/Cloud Backend
Fix Terraform's remote/cloud backend '401 Unauthorized' error: diagnose invalid API tokens, missing credentials blocks, wrong hostname, and TF_TOKEN environment variables.
- #terraform
- #iac
- #troubleshooting
- #errors
Stuck on this Terraform error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Exact Error Message
╷
│ Error: Failed to get existing workspaces: unauthorized
│
│ Terraform failed to fetch workspaces from the backend. The error was: 401 Unauthorized.
│ Please check your API token and try again.
╵
With HCP Terraform / Terraform Enterprise you may instead see:
╷
│ Error: Required token could not be found
│
│ Run "terraform login" to obtain and save credentials for the host, or set the
│ TF_TOKEN_app_terraform_io environment variable.
╵
What It Means
Terraform’s remote and cloud backends talk to HCP Terraform (formerly Terraform Cloud), Terraform Enterprise, or another API-driven state host over HTTPS. Every request carries a bearer token. A 401 Unauthorized means the backend received your request but rejected the credential: the token is missing, malformed, expired, revoked, or scoped to a different organization than the one your configuration targets.
This is an authentication failure, not a network or configuration-syntax failure. Terraform reached the host successfully — the host simply refused to authorize the operation. It surfaces most often on terraform init, on the first plan, or right after a token was rotated.
Common Causes
- No token is stored for the host and no
TF_TOKEN_*environment variable is set. - The stored credential in
~/.terraform.d/credentials.tfrc.jsonis stale after a token rotation or aterraform logout. - A user/team API token was revoked, or a team token lost access to the target organization.
- The
hostnamein thecloud/remoteblock does not match the host the token was issued for (for exampleapp.terraform.iovs a private Terraform Enterprise domain). - In CI, the
TF_TOKEN_app_terraform_iovariable is unset, truncated, or contains stray whitespace/quotes. - The token belongs to a different organization than the one named in the backend block.
Diagnostic Commands
Confirm which host and organization your configuration targets:
terraform version
grep -R "cloud\|backend\|organization\|hostname" *.tf
Check whether a credential is actually stored for the host:
cat ~/.terraform.d/credentials.tfrc.json
Verify the token directly against the API (a valid token returns 200 and your account JSON; a bad one returns 401):
curl -sS -o /dev/null -w "%{http_code}\n" \
--header "Authorization: Bearer $TF_TOKEN_app_terraform_io" \
https://app.terraform.io/api/v2/account/details
Re-run init with debug logging to see exactly which host is challenged:
TF_LOG=DEBUG terraform init 2>&1 | grep -iE "unauthorized|token|host"
Step-by-Step Resolution
- Identify the exact hostname. Open your backend configuration and note the
hostname(defaults toapp.terraform.iofor thecloudblock):
terraform {
cloud {
organization = "my-org"
hostname = "app.terraform.io"
workspaces {
name = "production"
}
}
}
- Obtain and store a fresh token interactively. This writes
credentials.tfrc.jsonfor you:
terraform login app.terraform.io
- For CI or non-interactive runs, export a token as an environment variable instead. The variable name is the hostname with dots replaced by underscores:
export TF_TOKEN_app_terraform_io="$(cat /run/secrets/tfe_token)"
terraform init
-
If the token is correct but still rejected, confirm it has access to the organization named in the block. Generate a new team or organization token scoped to that org from the HCP Terraform UI (Settings → Teams/Tokens), then repeat step 3.
-
Clear any stale credential that might shadow the new one, then re-init:
terraform logout app.terraform.io
terraform login app.terraform.io
terraform init -reconfigure
- Confirm success —
initshould now list workspaces without a 401:
Initializing HCP Terraform...
Terraform Cloud has been successfully initialized!
If you are automating token setup and secret plumbing across many pipelines, the Terraform CI credentials prompts in the prompt library can generate the environment-variable and secrets wiring for your specific CI platform.
Prevention
- Prefer
TF_TOKEN_<host>environment variables in CI over baking credentials into files or the repository. - Store the token in a secrets manager and inject it at run time; never commit
credentials.tfrc.json. - Use organization/team tokens for automation and user tokens for humans, so rotating one does not break the other.
- Set explicit token expiry and rotate on a schedule, updating the CI secret in the same change.
- Pin the
hostnamein the backend block so a copied config cannot silently target the wrong host. - Trim whitespace and quotes when injecting tokens; a trailing newline is a common silent cause of 401s.
Related Errors
Required token could not be found— no credential stored at all, rather than a rejected one.Error: Failed to get existing workspaces: ... 403 Forbidden— authenticated but not permitted (RBAC), not a bad token.Error: workspace "..." not found— the token is valid but the named workspace does not exist or is not visible.no valid credential sources found— an AWS credential problem, not an HCP Terraform token problem.
Frequently Asked Questions
Where does terraform login store the token? It writes a JSON credentials block to ~/.terraform.d/credentials.tfrc.json keyed by hostname; delete or overwrite that entry to force re-authentication.
Why does CI get a 401 when my laptop works? Your laptop has a stored credential from terraform login, but CI has none unless you set TF_TOKEN_<host> or provide a credentials file; export the environment variable in the pipeline.
How do I build the TF_TOKEN_* variable name for a private host? Take the backend hostname and replace every dot with an underscore, so tfe.example.com becomes TF_TOKEN_tfe_example_com.
Could the token be valid but still rejected? Yes — if it is scoped to a different organization than the one in your cloud block, the backend returns 401/403; issue a token for the correct org. For more state-backend fixes, see the Terraform guides.
Fixed it? Get 500 Terraform & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Stuck on this? Start guided troubleshooting
Open an interactive diagnostic session with this error already loaded. Work a step-by-step plan, record what each check returns, land on a root cause, and export a clean incident summary — no account needed to start.
Did this fix your issue?
Solved it a different way?
Share the fix that worked for you — reviewed, then published to help the next engineer.
That looks like it may contain a secret (key, token, password, or connection string). Please remove it — a note with a detected secret can’t be published.
Thanks — that helps. Published notes appear after a quick review.
Trending errors this week
The error guides other engineers are actually reading right now.
- 1mount: wrong fs type, bad option, bad superblock
- 2Docker 'failed to set up container networking': Fix the Bridge and IP Pool
- 3Docker 'failed to create shim task': How to Fix the containerd Runtime Error
- 4Transport endpoint is not connected
- 5modprobe: FATAL: Module not found
- 6mount: wrong fs type, bad option, bad superblock
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.