pulumi/pulumi · error · ErrUnauthorized
Unauthorized: No credentials provided or are invalid.
Error message
Unauthorized: No credentials provided or are invalid.
What it means
ErrUnauthorized is the Pulumi Cloud backend's sentinel error indicating no valid credentials were presented to the service. Code paths use errors.Is(err, ErrUnauthorized) to detect when login/signup is required.
Source
Thrown at pkg/backend/httpstate/backend.go:80
"github.com/pulumi/pulumi/sdk/v3/go/common/env"
"github.com/pulumi/pulumi/sdk/v3/go/common/promise"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/config"
"github.com/pulumi/pulumi/sdk/v3/go/common/slice"
"github.com/pulumi/pulumi/sdk/v3/go/common/tokens"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/agentdetect"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/logging"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/result"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/retry"
"github.com/pulumi/pulumi/sdk/v3/go/common/workspace"
"github.com/pulumi/pulumi/sdk/v3/go/property"
"go.opentelemetry.io/otel"
oteltrace "go.opentelemetry.io/otel/trace"
)
var ErrUnauthorized = errors.New("Unauthorized: No credentials provided or are invalid.")
type agentCredentialUseContextKey struct{}
type agentCredentialUse struct {
sync.Mutex
cloudURLs map[string]bool
}
// ContextWithAgentCredentialUse returns a context that tracks shared temporary
// agent credential use for one CLI command.
func ContextWithAgentCredentialUse(ctx context.Context) context.Context {
return context.WithValue(ctx, agentCredentialUseContextKey{}, &agentCredentialUse{
cloudURLs: map[string]bool{},
})
}
func agentCredentialUseFromContext(ctx context.Context) *agentCredentialUse {
use, _ := ctx.Value(agentCredentialUseContextKey{}).(*agentCredentialUse)View on GitHub (pinned to 793f7b2e16)
Solutions
- Run `pulumi login` to authenticate interactively
- Set a valid PULUMI_ACCESS_TOKEN (create one at the Pulumi Cloud console) for headless/CI use
- Check the credentials file (~/.pulumi/credentials.json) for stale entries for the cloud URL and re-login
- Verify you are pointing at the intended cloud URL (default https://api.pulumi.com)
Example fix
// before (CI)
run: pulumi up
// after
env:
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
run: pulumi up Defensive patterns
Strategy: fallback
Validate before calling
// Go caller check before using the backend
if os.Getenv("PULUMI_ACCESS_TOKEN") == "" {
if _, err := os.Stat(filepath.Join(home, ".pulumi", "credentials.json")); err != nil {
return ErrUnauthorized // prompt for login first
}
} Try / catch
_, err := httpstate.New(ctx, d, cloudURL, project, insecure)
if errors.Is(err, backend.ErrUnauthorized) {
// run `pulumi login` or set PULUMI_ACCESS_TOKEN, then retry
} Prevention
- Run `pulumi login` before first use on a machine
- Set PULUMI_ACCESS_TOKEN in CI secrets; rotate tokens before expiry
- Match the cloud URL to where your token was issued
When it happens
Trigger: Calling httpstate backend operations (login, account validation, agent credential flows) with an empty/invalid/expired PULUMI_ACCESS_TOKEN or no stored credentials for the cloud URL; TestCurrent* and validateStoredAccount paths hit it when the API rejects the token.
Common situations: Never running `pulumi login`; PULUMI_ACCESS_TOKEN env var unset, typo'd, or revoked; token expired on CI machines; switching cloud URLs (PULUMI_CLOUD_URL) where no account is stored.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- getting stored credentials: %w
- unexpected response from server
- -32000
- -32000
- editing an organization member requires the Pulumi Cloud bac
AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31).
Data as JSON: /api/errors/623b3bbe3e94c554.
Report an issue: GitHub.