{"record":{"id":"f961efd6b29d94a0","repo":"hashicorp/terraform","slug":"token-is-invalid-s","errorCode":null,"errorMessage":"Token is invalid: %s","messagePattern":"Token is invalid: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/login.go","lineNumber":662,"sourceCode":"\t\tdiags := diags.Append(fmt.Errorf(\"Failed to retrieve token: %s\", err))\n\t\treturn \"\", diags\n\t}\n\n\ttoken = strings.TrimSpace(token)\n\tcfg := &tfe.Config{\n\t\tAddress:  service.String(),\n\t\tBasePath: service.Path,\n\t\tToken:    token,\n\t\tHeaders:  make(http.Header),\n\t}\n\tclient, err := tfe.NewClient(cfg)\n\tif err != nil {\n\t\tdiags = diags.Append(fmt.Errorf(\"Failed to create API client: %s\", err))\n\t\treturn \"\", diags\n\t}\n\tuser, err := client.Users.ReadCurrent(context.Background())\n\tif err == tfe.ErrUnauthorized {\n\t\tdiags = diags.Append(fmt.Errorf(\"Token is invalid: %s\", err))\n\t\treturn \"\", diags\n\t} else if err != nil {\n\t\tdiags = diags.Append(fmt.Errorf(\"Failed to retrieve user account details: %s\", err))\n\t\treturn \"\", diags\n\t}\n\tc.Ui.Output(fmt.Sprintf(c.Colorize().Color(\"\\nRetrieved token for user [bold]%s[reset]\\n\"), user.Username))\n\n\treturn svcauth.HostCredentialsToken(token), nil\n}\n\nfunc (c *LoginCommand) interactiveContextConsent(hostname svchost.Hostname, grantType disco.OAuthGrantType, credsCtx *loginCredentialsContext) (bool, tfdiags.Diagnostics) {\n\tvar diags tfdiags.Diagnostics\n\tmechanism := \"OAuth\"\n\tif grantType == \"\" {\n\t\tmechanism = \"your browser\"\n\t}\n\n\tc.Ui.Output(fmt.Sprintf(\"Terraform will request an API token for %s using %s.\\n\", hostname.ForDisplay(), mechanism))","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/login.go#L644-L680","documentation":"Thrown during `terraform login` after `client.Users.ReadCurrent` returns exactly `tfe.ErrUnauthorized`. The API client was constructed successfully (error 640 did not fire), the token was sent to the `/api/v2/account/details` endpoint, and the server responded with HTTP 401. This means the token format was acceptable to the client library but the server rejected it as invalid, expired, or revoked.","triggerScenarios":"`client.Users.ReadCurrent` issues `GET /api/v2/account/details` with the `Authorization: Bearer <token>` header. The server returns 401, which go-tfe maps to `tfe.ErrUnauthorized`, and this branch (`err == tfe.ErrUnauthorized`) catches it distinctly from other failures.","commonSituations":"User pasted an expired or revoked API token; user pasted a token from a different HCP Terraform organization or a different TFE instance; token was truncated or had stray whitespace beyond what `TrimSpace` removed (e.g. embedded newline); token belongs to a team with no access to the current user scope.","solutions":["Generate a fresh token at `https://app.terraform.io/app/settings/tokens` (or the equivalent TFE settings page) and re-run `terraform login`.","Confirm the token was copied in full — HCP Terraform tokens are 208+ characters; check for truncation.","Verify the token is for the same hostname/instance you are logging in to.","If the token was recently revoked or rotated, update any credential helpers or `.terraformrc` that may supply a stale value."],"exampleFix":"// The token typed at the prompt is rejected by the server.\n// Re-generate: https://app.terraform.io/app/settings/tokens\n// Then: terraform login app.terraform.io\n// paste the NEW token at the 'Token for app.terraform.io:' prompt","handlingStrategy":"validation","validationCode":"// Before scripting a login, sanity-check token length/format.\n// HCP Terraform tokens are long opaque strings (typically 200+ chars).\ntoken = strings.TrimSpace(token)\nif len(token) < 100 {\n    return errors.New(\"token looks truncated; re-copy the full token from the UI\")\n}","typeGuard":"null","tryCatchPattern":"// After login, detect 401 specifically:\nif errors.Is(err, tfe.ErrUnauthorized) {\n    // prompt the user to regenerate the token\n}","preventionTips":["Generate tokens with a clear expiration and rotation reminder.","Store tokens in a credentials helper or secret manager rather than copy-pasting.","Confirm the token's hostname/instance scope before use."],"tags":["terraform","login","authentication","unauthorized","token"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}