Skip to content
Latchkey

HCP Terraform "terraform login" 401 Unauthorized in CI

HCP Terraform returned 401 Unauthorized. The request reached the API but the token was not accepted: it was blank, expired, revoked, or malformed. The host is up; the credential is the problem.

What this error means

A step that hits the HCP Terraform API (or a non-interactive terraform login flow) fails with "401 Unauthorized" or "Invalid token". Public unauthenticated calls behave differently, so it is not a network issue.

terraform
Error: Failed to request discovery document: 401 Unauthorized

There was a problem with the API token used to authenticate to app.terraform.io.

Common causes

The token is expired or revoked

User and team tokens can expire or be revoked; a revoked token still reaches the API but is rejected with 401.

The secret was never injected

The CI step ran without the token variable set, so an empty or default value was sent and rejected.

How to fix it

Regenerate and re-inject the token

  1. Create a fresh API token in HCP Terraform.
  2. Update the CI secret with the new value.
  3. Expose it as TF_TOKEN_app_terraform_io (or the credentials file) in the step.
.github/workflows/ci.yml
env:
  TF_TOKEN_app_terraform_io: ${{ secrets.TF_API_TOKEN }}

Confirm the secret is actually set

A 401 with an obviously empty token usually means the secret name is wrong or the job lacks access to it. Verify the secret exists and the step can read it.

How to prevent it

  • Rotate HCP Terraform tokens on a schedule and update the secret in one place.
  • Prefer team tokens for pipelines so a departing user does not break CI.
  • Fail fast if the token variable is empty before running Terraform.

Frequently asked questions

What causes ""401 Unauthorized" during terraform login"?
User and team tokens can expire or be revoked; a revoked token still reaches the API but is rejected with 401.
How do I fix "401 Unauthorized" during terraform login?
Regenerate and re-inject the token

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card