{"record":{"id":"e6f91ea781423da9","repo":"hashicorp/terraform","slug":"login-cancelled","errorCode":null,"errorMessage":"Login cancelled","messagePattern":"Login cancelled","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/command/login.go","lineNumber":373,"sourceCode":"// Synopsis implements cli.Command.\nfunc (c *LoginCommand) Synopsis() string {\n\treturn \"Obtain and save credentials for a remote host\"\n}\n\nfunc (c *LoginCommand) defaultOutputFile() string {\n\tif c.CLIConfigDir == \"\" {\n\t\treturn \"\" // no default available\n\t}\n\treturn filepath.Join(c.CLIConfigDir, \"credentials.tfrc.json\")\n}\n\nfunc (c *LoginCommand) interactiveGetTokenByCode(hostname svchost.Hostname, credsCtx *loginCredentialsContext, clientConfig *disco.OAuthClient) (*oauth2.Token, tfdiags.Diagnostics) {\n\tvar diags tfdiags.Diagnostics\n\n\tconfirm, confirmDiags := c.interactiveContextConsent(hostname, disco.OAuthAuthzCodeGrant, credsCtx)\n\tdiags = diags.Append(confirmDiags)\n\tif !confirm {\n\t\tdiags = diags.Append(errors.New(\"Login cancelled\"))\n\t\treturn nil, diags\n\t}\n\n\t// We'll use an entirely pseudo-random UUID for our temporary request\n\t// state. The OAuth server must echo this back to us in the callback\n\t// request to make it difficult for some other running process to\n\t// interfere by sending its own request to our temporary server.\n\treqState, err := uuid.GenerateUUID()\n\tif err != nil {\n\t\t// This should be very unlikely, but could potentially occur if e.g.\n\t\t// there's not enough pseudo-random entropy available.\n\t\tdiags = diags.Append(tfdiags.Sourceless(\n\t\t\ttfdiags.Error,\n\t\t\t\"Can't generate login request state\",\n\t\t\tfmt.Sprintf(\"Cannot generate random request identifier for login request: %s.\", err),\n\t\t))\n\t\treturn nil, diags\n\t}","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/login.go#L355-L391","documentation":"Returned by `terraform login` when the user answers \"no\" to the OAuth authorization-code consent prompt shown by `interactiveContextConsent` before the code-grant flow begins. It is a deliberate user abort, not a library failure: the command appends it as a diagnostic and returns no token.","triggerScenarios":"`LoginCommand.interactiveGetTokenByCode` runs for a host whose disco metadata advertises an OAuth authorization-code grant; `interactiveContextConsent` returns `confirm=false` because the user typed a negative answer at the consent prompt.","commonSituations":"Running `terraform login app.terraform.io` (or a private TFE hostname) in a terminal and selecting \"no\" / typing something other than yes when asked to approve the authorization request; CI shells where stdin returns an empty or non-affirmative answer.","solutions":["Re-run `terraform login <hostname>` and answer \"yes\" at the consent prompt to proceed with the OAuth code grant.","If running non-interactively, set the credentials directly in ~/.terraform.d/credentials.tfrc.json or supply a TF_TOKEN_<hostname> environment variable instead of using the interactive flow.","Verify the hostname argument matches a host that actually serves `terraform-login` disco metadata."],"exampleFix":"// before: terraform login app.terraform.io  -> user types 'no'\n// after:  terraform login app.terraform.io  -> user types 'yes' at consent","handlingStrategy":"validation","validationCode":"// Before invoking the login flow, gate on input capability:\nif !cmd.Input() {\n    return errors.New(\"cannot perform interactive OAuth login with input disabled; set TF_TOKEN_<host> instead\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not run `terraform login` under `-input=false`; it always requires a consent prompt.","For automation, supply credentials via TF_TOKEN_<hostname> or credentials.tfrc.json rather than the interactive flow.","If you wrap Terraform, treat 'Login cancelled' as a non-retryable user decision, not a transient error."],"tags":["login","oauth","user-cancel","interactive","terraform-cli"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}