Azure Cosmos DB 403 Forbidden: data-plane role missing or key blocked
Cosmos DB 403s have three distinct causes: no data-plane role assignment (identity auth), IP firewall blocking the client, or disableLocalAuth blocking keys. The fix depends on which. Not for different error messages.
TL;DR: Cosmos DB 403s have three distinct causes: no data-plane role assignment (identity auth), IP firewall blocking the client, or disableLocalAuth blocking keys. The fix depends on which. Confirm which: run the same operation from the portal's Data Explorer (uses its own auth path).
The error
container.item(id, wrongPk).read()The fix
- Identity without data role. If using DefaultAzureCredential / aadCredentials, the identity needs a Cosmos DB data-plane role:
az cosmosdb sql role assignment create --account-name [account] -g [rg] --role-name "Cosmos DB Built-in Data Contributor" --principal-id [oid] --scope /. Subscription Contributor is irrelevant here. - IP firewall. Account networking set to "selected networks" and your client IP is not allow-listed. Portal shows allowed IPs; add yours or use a private endpoint.
- disableLocalAuth. If the account has local (key) auth disabled and your code passes a key, every call 403s. Switch the code to identity.
- Partition key mismatch on point reads.
container.item(id, wrongPk).read()can surface as 404, but combined with firewall/RBAC confusion it gets misdiagnosed as 403. Rule it out with a known-good point read. Confirm which: run the same operation from the portal's Data Explorer (uses its own auth path). If Data Explorer works, the account is fine and the problem is your client's auth or network. If Data Explorer also 403s, it is the account firewall or RBAC.
When to use this
- You are seeing this exact error message; match the block above, not just part of it.
- The failing call matches the scenario in the title: Azure Cosmos DB 403 Forbidden.
- You want the fastest verified fix before digging through logs.
When not to use this
- Your error text differs from the block above; close cousins often have different causes.
- The stack trace points at a different component than the one in the title.
- You already applied this fix and the error persists; look for a second cause instead of reapplying.
Compatibility
- Not pinned to a specific version; follows current Azure behavior.