wrangler auth failed: API token missing the workers:write permission
Fixes wrangler deploys rejected because the API token lacks the workers:write permission (or a sibling scope). Use when auth succeeds but deploy, secret, or KV operations fail with permission errors. Not for expired tokens, wrong-account errors, or OAuth login failures.
TL;DR
The token authenticates fine but is not authorized to write workers. Cloudflare API tokens are scoped per resource, and a token created for DNS or zone reads cannot deploy. Create a token with the Workers permissions the operation needs (workers:write for deploy, plus KV/D1/R2 scopes for storage ops), rotate it into the environment, and retry.
The query
wrangler auth failed: API token missing the workers:write permissionUse this when
wrangler whoamiworks butwrangler deployfails with a permissions error.- The token was created for a different purpose (DNS, analytics) and reused.
- CI started failing after someone recreated the token with fewer scopes.
Not for
- 'authentication error, check your API token' (token invalid, not under-scoped).
- Tokens that expired (rotation problem, separate fix).
- OAuth login failures in interactive sessions.
Steps
Step 1: Confirm the token identity and its failure mode
npx wrangler whoami
npx wrangler deploy --dry-runExpected result: whoami succeeds, deploy fails naming permissions. That split proves auth works and scope is the problem.
Step 2: Create a correctly scoped token
In the Cloudflare dashboard under API tokens, create a token with Account / Workers Scripts / Write (workers:write), and add KV, D1, R2, or Queue scopes only for the storage the worker uses. Scope it to the specific account, not all accounts.
Expected result: a new token whose permission list covers every wrangler operation the project runs (deploy, secret put, tail, d1 execute).
Step 3: Rotate the token in the environment
Replace the old token value in CI secrets and in local shell config. Never paste the token into chat, tickets, or the repo.
Expected result: the environment holds only the new token. Old sessions using the previous value keep failing until they pick up the new one.
Step 4: Verify end to end
npx wrangler whoami
npx wrangler deploy --dry-runExpected result: both succeed. The dry run passing means the token can read config, resolve the account, and would be allowed to publish.
Step 5: Deploy
npx wrangler deployExpected result: the deploy completes. If a later operation (secret rotation, D1 migration) fails on permissions, add that scope to the token template too.
Why it happens
Least-privilege token templates are the default recommendation, so teams create minimal tokens and then reuse them for operations outside the original scope. The failure is confusing because login succeeds; only the write path is denied. Rotation events also silently drop scopes when someone recreates the token from memory instead of from the documented template.
Edge cases
- Document the token template (exact scopes) in the deploy runbook. Every future rotation copies the template instead of improvising.
- Tokens scoped to 'All accounts' are a smell. Scope to the one account the project deploys to.
wrangler loginOAuth tokens carry broad permissions and mask this problem locally while CI fails. Always test CI's token, not your own.- Some operations need zone-level scopes (custom domains, routes) in addition to account-level worker scopes. Add them when route management is part of the deploy.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_X567pMmMwLJAYNdcqGyQRg