KB-006: D1 Authorization Error (7403) - API Token Missing D1:Edit Permission
KB-006: D1 Authorization Error (7403) - API Token Missing D1:Edit Permission
Symptom
CI/CD deployment to Cloudflare fails during D1 migration step with:
✘ [ERROR] A request to the Cloudflare API (/accounts/***/d1/database/***) failed. The given account is not valid or is not authorized to access this service [code: 7403]The error occurs even after creating a new API token with “Workers:Edit” and “Pages:Edit” permissions.
Root Cause
Cloudflare separates resource permissions granularly. D1:Edit is a distinct permission from Workers:Edit and Pages:Edit.
Common mistake: Creating an API token with only Workers and Pages permissions, assuming Workers:Edit covers all Worker-related resources including D1 databases.
Error Codes
- 7403: Authorization error - the API token is valid but lacks permission for the requested resource
- 10000: Authentication error - the API token is invalid or expired
The previous deployment workflow only detected error 10000, so on 7403 errors it would retry 3 times and then fail without helpful guidance.
Solution
Step 1: Update Your Cloudflare API Token
- Go to Cloudflare API Tokens
- Find your existing API token OR click “Create Token”
- Ensure it has all three of these permissions:
- ✅ Account > D1:Edit (REQUIRED for database migrations)
- ✅ Account > Workers:Edit (for worker deployment)
- ✅ Account > Pages:Edit (for Pages deployment)
- Save the token
Step 2: Update GitHub Secret
- Go to your repository Settings → Secrets and variables → Actions
- Update the
CLOUDFLARE_API_TOKENsecret with your new token - Re-run the failed workflow
Prevention
When creating Cloudflare API tokens for CI/CD, always include:
Account Permissions: • D1:Edit ← Don't forget this! • Workers:Edit • Pages:Edit • Workers KV Storage:Edit (if using KV) • Workers R2 Storage:Edit (if using R2) • Account Analytics:Read (optional, for observability)Related Issues
- This issue affects all workflows that run D1 migrations:
.github/workflows/ci.yml(Deploy to Cloudflare job).github/workflows/db-migrate.yml- Any workflow using
.github/actions/deploy-worker/action.yml
Fix Applied
The deployment action now detects both error classes and handles them in separate branches, so it can provide the correct guidance for authorization failures (7403 / not authorized) versus authentication failures (10000):
if echo "$output" | grep -qiE 'not authorized|7403'; then # Provides D1:Edit permission guidanceelif echo "$output" | grep -qiE 'Authentication error|10000'; then # Provides API token invalid/expired guidancefiVerification
After updating the API token, the next deployment should succeed. If it still fails:
- Verify
CLOUDFLARE_ACCOUNT_IDis correct (check wrangler.toml or Cloudflare dashboard) - Confirm the D1 database exists:
deno task wrangler d1 list - Check the database ID matches
wrangler.toml:database_id = "..."
References
- Cloudflare API Token Permissions
- D1 Documentation
- PR fixing this issue: #1507