Guushu Studio / Notes

Wrangler authentication error 10000 with a per-Worker API token

Wrangler authentication error 10000 on a per-Worker Editor token: why verify says active, the first call wrangler makes, and 4 scope gaps that still fail.

By · · updated

Between Sep 15 and Sep 18, 2026, at least seven Cloudflare Community threads had the same shape. An account-owned token had Individual Workers, Editor on one existing Worker. tokens/verify said active. Then wrangler deploy stopped on its first API call with Wrangler authentication error 10000.

I answered one of those threads on Sep 18. That afternoon a Cloudflare staff member posted that they'd fixed an issue behind it. The platform bug is gone, but the same error still shows up for reasons that are your config, and the checks below tell the two apart.

What happened between Sep 15 and Sep 18

The Workers roles and permissions page, which introduced per-Worker roles, was updated on Sep 15. Its Wrangler table says deploying an existing Worker needs Editor for that Worker, nothing more. People built tokens exactly that way and hit 403 with code 10000.

When (UTC)What
Sep 15Per-Worker roles documented. The first threads with 403 / 10000 appear
Sep 17, 09:25Staff reply in Individual Worker Editor token rejected with error 10000: can't reproduce, and posts a successful response from a per-Worker Editor token
Sep 18, 14:50Same thread: "We've fixed an issue that I believe affected this request"

If your token dates from that week and still fails, re-run the same request once before touching the token. If it now works, you were caught by that bug.

Why does tokens/verify say active when the deploy fails?

Because verify doesn't check permissions. Cloudflare's create token guide says the endpoint fetches the current status of the token. That tells you it exists and isn't expired or revoked. A 200 there and a 403 on a Worker aren't a contradiction, and verify can't tell you whether a scope is right.

There's also a second trap: there are two verify endpoints. User-owned tokens use /user/tokens/verify, and account-owned tokens use /accounts/<id>/tokens/verify. I tried both with a user-owned token I keep for analytics reads. The first returned "status": "active". The second returned 1000 Invalid API Token for the same token, same account.

The first API call wrangler deploy makes

In the workers-sdk source, validate-worker-props.ts reads the Worker's metadata from /accounts/<id>/workers/services/<name> before it uploads anything. That's where the threads failed, so it's the request to reproduce by hand:

curl -s "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/services/$WORKER" \
  -H "Authorization: Bearer $CF_TOKEN" | jq '{success, errors}'

With a working per-Worker Editor token this returns "success": true and the Worker's metadata. With code 10000 it's worth comparing against the successful response posted in the staff reply before rebuilding the token again.

The --env suffix: a name the token was never given

A per-Worker role is granted to a Worker name, and wrangler deploy --env production doesn't deploy the name at the top of your config. It deploys <name>-production.

My own home page Worker is app-home in wrangler.jsonc and deploys with --env production. Running the curl above on 2026-09-30 with a token that has no Workers permission at all gave three different answers:

Name requestedResponse
app-home10090 This Worker does not exist on this account.
app-home-productionNo access to the specified service.
A made-up name10090 This Worker does not exist on this account.

So "does not exist" can mean you asked for the unsuffixed name, and "no access" means the Worker exists but your token isn't allowed near it. If you scoped the token in the dashboard by picking the Worker from a list, check that you picked the suffixed one.

Four things a per-Worker Editor token still can't do

The same docs page lists the gaps. They're the reasons a correctly scoped token can still fail on the day the platform is fine:

ActionWhat it needs
Create a Worker that doesn't exist yetProduct-level Admin. Per-Worker roles can't apply to a Worker that isn't there
Add, change or remove Routes or Custom DomainsEditor on the Worker plus Zone, Workers Routes, Write on every affected zone
Custom Domains with per-Worker rolesNot supported yet. The Limitations section says support is planned
Query D1, read KV keys, list R2 objects directlyPermissions on that resource. Deploying with bindings doesn't need them

The second row catches deploys that look harmless. If your wrangler config lists routes or a custom_domain, a deploy that changes them needs the zone permission too. The docs say later deploys only need Editor, as long as they don't add, update or remove that connection.

A minimal CI token for one Worker

For a deploy-only pipeline I'd build the token from the table up. Start with Individual Workers, Editor on the exact deployed name, suffix included. Add Zone, Workers Routes, Write on the zone only if the pipeline changes routes. Add nothing for bindings unless a step queries D1 or KV directly.

My own home page deploy token is older than per-Worker roles and has Workers Routes and DNS edit on the zone, because its config binds two Custom Domains. I can't shrink it to one Worker yet, and that's the third row of the table in practice. Scoped tokens with an expiry are also item 11 in my Cloudflare zone security checklist, which has the read-only command for listing the tokens you already have.

The usage collector I run needs one Account Analytics Read token and nothing else. The hosted version is a one-question form today, not a product: guard.guushu.com.