The symptom
I moved a domain between two Cloudflare accounts, logged out of the old one, logged into the new one, and redeployed. wrangler answered with:
✘ [ERROR] A request to the Cloudflare API failed.
Authentication error [code: 10000]
The useful detail was in the request URL rather than the message: it was calling the API against the previous account's ID. Not a permissions problem, not an expired token. wrangler was authenticated perfectly well as the new user and asking about an account that user had never had access to.
The obvious things all failed to help. Logging out and back in again, a fresh
wrangler login, regenerating the API token, and checking the config
for a stray account_id that was not there. The error did not move.
Where the old account lives
When your login has access to exactly one account, wrangler resolves it once and caches the answer in your project directory:
.wrangler/cache/wrangler-account.json
It is a sensible cache — the lookup is a network round trip on every deploy
otherwise. What it does not do is notice that the identity behind it changed.
wrangler logout clears your credentials; it leaves this file alone.
So the next deploy authenticates as the new user and then reads a stale account
ID off disk, which is a combination the API has no polite response to.
The reason it is hard to find is that the file is inside a
.wrangler/ directory that is gitignored and that you have never
had a reason to open. Nothing in the error mentions it.
The fix
Delete the file and deploy again:
rm -f .wrangler/cache/wrangler-account.json && npx wrangler deploy
wrangler re-resolves the account against your current login and writes a fresh cache. That is the whole fix.
If you switch between accounts regularly, set the account explicitly instead and take the cache out of the decision entirely:
CLOUDFLARE_ACCOUNT_ID=... npx wrangler deploy
Worth adding to any project README that has ever changed hands. The next person to hit this will otherwise spend the same hour regenerating tokens that were never the problem.
Why the domain has to be in the same account
The reason I was moving accounts in the first place is a constraint worth stating plainly, because it decides how you organise things later: a Worker can only bind a custom domain that belongs to its own Cloudflare account. The zone and the Worker have to live together.
If you find yourself with the domain in a personal account and the Worker in a company one, moving the zone is the fix, and it is less painful than it sounds — Cloudflare keeps the DNS records. But do it before you attach anything, not after, and expect to clear that cache file on the other side.