pulumi/pulumi · error

this command requires logging in; try running `esc login` fi

Error message

this command requires logging in; try running `esc login` first

What it means

The Pulumi ESC CLI client returns this error when an authenticated API call receives an HTTP 401 response while no API token is configured (pc.apiToken == ""). It is a friendlier replacement for a generic unauthorized error, telling the user they must authenticate with `esc login` before running commands that hit the Pulumi Cloud API.

Source

Thrown at pkg/cmd/esc/cli/client/client.go:1798

	}

	if opts.GzipCompress {
		// If we're sending something that's gzipped, set that header too.
		req.Header.Set("Content-Encoding", "gzip")
	}

	resp, err := doWithRetry(pc.httpClient, req, opts.RetryPolicy)
	if err != nil {
		// Don't wrap *apitype.ErrorResponse.
		if _, ok := err.(*apitype.ErrorResponse); ok {
			return nil, err
		}
		return nil, fmt.Errorf("performing HTTP request: %w", err)
	}

	// Provide a better error if using an authenticated call without having logged in first.
	if resp.StatusCode == 401 && pc.apiToken == "" {
		return nil, errors.New("this command requires logging in; try running `esc login` first")
	}

	// Provide a better error if rate-limit is exceeded(429: Too Many Requests)
	if resp.StatusCode == 429 {
		return nil, errors.New("esc: request rate-limit exceeded")
	}

	// For 4xx and 5xx failures, attempt to provide better diagnostics about what may have gone wrong.
	if resp.StatusCode >= 400 && resp.StatusCode <= 599 {
		// 4xx and 5xx responses should be of type ErrorResponse. See if we can unmarshal as that
		// type, and if not just return the raw response text.
		respBody, err := io.ReadAll(resp.Body)
		if err != nil {
			return nil, fmt.Errorf("API call failed (%s), could not read response: %w", resp.Status, err)
		}

		reqID := ""
		if resp.StatusCode >= 500 {

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Run `esc login` to authenticate and store an API token
  2. Verify the token is available in your environment (e.g. PULUMI_ACCESS_KEY) and has not expired
  3. Check you are pointing at the intended backend URL (PULUMI_BACKEND_URL / cloud URL) so existing credentials are used
  4. Re-login if the token was revoked or rotated recently

Example fix

// before (CI without auth)
- run: esc env get my-org/my-proj/my-env
// after
- run: esc login --auth-mode access-key
- run: esc env get my-org/my-proj/my-env
Defensive patterns

Strategy: validation

Validate before calling

// Go: check credentials before invoking esc client calls
func ensureLoggedIn(client *escclient.Client) error {
    if client == nil || !hasAPIToken() {
        return errors.New("run `esc login` before running this command")
    }
    return nil
}

Try / catch

// Go
ref, err := client.GetEnvironment(ctx, org, proj, env)
if err != nil {
    if strings.Contains(err.Error(), "requires logging in") {
        return fmt.Errorf("not logged in: run `esc login` first: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Any esc client call that goes through the HTTP request path when the server responds with status 401 and the client was constructed without an API token — e.g. running `esc env get`, `esc env set`, or `esc open` in a fresh environment or after credentials were cleared/rotated.

Common situations: Running ESC commands on a new machine or CI runner without logging in; PULUMI_ACCESS_KEY/token env vars unset or expired; token revoked server-side; using the wrong backend URL so stored credentials don't apply.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/30c4a82192f9ea50. Report an issue: GitHub.