hashicorp/terraform · error

Token is invalid: %s

Error message

Token is invalid: %s

What it means

Thrown by the browser token login flow when the TFE API call client.Users.ReadCurrent returns tfe.ErrUnauthorized. This means the pasted token was syntactically accepted by the client but rejected by the API as not valid (revoked, wrong scope, expired, or typo'd).

Source

Thrown at internal/command/login.go:662

		diags := diags.Append(fmt.Errorf("Failed to retrieve token: %s", err))
		return "", diags
	}

	token = strings.TrimSpace(token)
	cfg := &tfe.Config{
		Address:  service.String(),
		BasePath: service.Path,
		Token:    token,
		Headers:  make(http.Header),
	}
	client, err := tfe.NewClient(cfg)
	if err != nil {
		diags = diags.Append(fmt.Errorf("Failed to create API client: %s", err))
		return "", diags
	}
	user, err := client.Users.ReadCurrent(context.Background())
	if err == tfe.ErrUnauthorized {
		diags = diags.Append(fmt.Errorf("Token is invalid: %s", err))
		return "", diags
	} else if err != nil {
		diags = diags.Append(fmt.Errorf("Failed to retrieve user account details: %s", err))
		return "", diags
	}
	c.Ui.Output(fmt.Sprintf(c.Colorize().Color("\nRetrieved token for user [bold]%s[reset]\n"), user.Username))

	return svcauth.HostCredentialsToken(token), nil
}

func (c *LoginCommand) interactiveContextConsent(hostname svchost.Hostname, grantType disco.OAuthGrantType, credsCtx *loginCredentialsContext) (bool, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	mechanism := "OAuth"
	if grantType == "" {
		mechanism = "your browser"
	}

	c.Ui.Output(fmt.Sprintf("Terraform will request an API token for %s using %s.\n", hostname.ForDisplay(), mechanism))

View on GitHub (pinned to c9def3e214)

Solutions

  1. Generate a fresh token in the browser (Tokens page) and re-run `terraform login` to paste it.
  2. Copy the token completely — verify no leading/trailing whitespace or truncation.
  3. Ensure the token is for the correct hostname/account (TFC vs your TFE instance).
  4. If the token is correct, check it was not revoked in the Tokens page.
Defensive patterns

Strategy: try-catch

Validate before calling

// Optionally sanity-check the token format before the API call (host-specific).
if strings.TrimSpace(token) == "" {
    return errors.New("token is empty; generate one in the browser first")
}

Try / catch

if _, err := client.Users.ReadCurrent(ctx); err != nil {
    if errors.Is(err, tfe.ErrUnauthorized) {
        // Token invalid/expired — prompt the user to regenerate and re-run login.
    }
    return err
}

Prevention

When it happens

Trigger: Produced during `terraform login` after a token is pasted, when client.Users.ReadCurrent returns exactly tfe.ErrUnauthorized. Triggered by an invalid/expired/revoked token or a token from a different user/account than expected.

Common situations: User pasted an expired or already-revoked token, copied the token incompletely, used a token from a different TFC organization/TFC vs TFE mismatch, or the token lacks permission to read the current user.

Understand the failure class

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/f961efd6b29d94a0. Report an issue: GitHub.