Cosmos DB for NoSQL errors — 403 network, RBAC and substatus codes, 429 throttling, 404, 409, 412, 413, 449 and 503, from TypeScript

What Cosmos DB for NoSQL errors mean and what to do — the 403s (firewall path messages, missing data-plane role, 5300 control-plane calls with an Entra token, 1014 full logical partition, 403.3 during failover), 429s (RU, metadata and transient, when 1–5% is healthy), 400 missing partition key, 404/1013, 409, 412 ETag, 413 2 MB, 423, 424, 449 and 503 — plus @azure/cosmos 4.10 code with Entra auth, retries and where the status and substatus live.

markdownreferencev1M49B-PH2Gstage: operatetrust: officialtrust: fieldservice: cosmos-dbinterface: sdkinterface: anyCosmos DB 403 ForbiddenRequest originated from client IP through public internetRequest originated from client VNET through private endpointRequest blocked by Authdoes not have required RBAC permissions to perform actionreadMetadata 403substatus 5300cannot be authorized by AAD token in data planeOperation 'POST' on resource 'calls' is not allowed through Azure Cosmos DB endpointCreateLeaseContainerIfNotExistssubstatus 1014Partition key reached maximum size403.3 write region failoverCosmos DB 429Request rate is largemetadata 429hot partition normalized RU consumptionCosmos DB 400 partition key missing404 substatus 1013409 Conflict id exists412 Precondition failure etag413 Entity too large 2 MB423 Locked scale operation424 Failed dependency TransactionalBatch449 Retry With503 Service Unavailable@azure/cosmosaadCredentialsErrorResponse substatusretryAfterInMsmaxRetryAttemptCount 9maxWaitTimeInSeconds 30customer-managed key substatus 4002

Created 21 Oct 2026 · Modified 23 Oct 2026 · 1 version

Cosmos DB for NoSQL errors

In @azure/cosmos, a failed call throws ErrorResponse: code is the HTTP status, substatus the sub-code, plus activityId (give it to support), retryAfterInMs, requestCharge and diagnostics.

403 Forbidden

Message / substatusCause → fix
Request originated from client IP {...} through public internet. / … from client VNET through service endpoint. / … through private endpoint.The network path isn't allowed. If the path is unexpected, fix the client (service endpoint missing on the subnet, DNS resolving the public IP instead of the private endpoint); if expected, fix public access, IP, VNet or private endpoint settings. Changes take up to 15 minutes
Request blocked by Auth : Request is blocked because principal [<id>] does not have required RBAC permissions to perform action [Microsoft.DocumentDB/databaseAccounts/readMetadata] on resource [/]. Learn more: https://aka.ms/cosmos-native-rbac. (as reported on Microsoft Q&A)No Cosmos data-plane role at that scope. Create a sqlRoleAssignment (Built-in Data Reader or Contributor); Azure RBAC roles, even Owner, don't help
Forbidden (403); Substatus: 5300; The given request [PUT ...] cannot be authorized by AAD token in data plane. / Operation 'POST' on resource 'calls' is not allowed through Azure Cosmos DB endpointCreating or deleting databases or containers (control plane) with an Entra token. Do it through Resource Manager (Bicep, CLI, management SDK) with Contributor or DocumentDB Account Contributor. Azure Functions Cosmos trigger: set CreateLeaseContainerIfNotExists to false and create the lease container yourself
Response status code does not indicate success: Forbidden (403); Substatus: 1014 / Partition key reached maximum size of {...} GBOne logical partition is full (20 GB): redesign the key (hierarchical keys)
403.3Write during a manual failover: SDKs follow the new write region; raw REST clients must re-read the account
403 (other)Expired token, storage quota reached, or a stored procedure blocked for high resource use

429 Too many requests

KindWhat to do
Request rate is large. More Request Units might be needed, so no changes were made.The partition's RU/s are used up. 1–5% of requests as 429 with acceptable latency is healthy. Otherwise look for a hot partition (one PartitionKeyRangeId near 100% normalized RU consumption while others idle): fix the key or spread the writes; then raise RU/s or use autoscale
The request didn't complete due to a high rate of metadata requests.Too many database/container create, read or list calls (system-reserved RU budget). More RU/s doesn't help: cache clients and container references, back off
The request didn't complete due to a transient service error.Retry; support case if it lasts minutes

The SDK retries 429s itself, by default up to 9 times within 30 seconds (connectionPolicy.retryOptions), so the metric can show 429s your code never sees.

Other status codes

StatusMeaning → fix
400Invalid JSON or query, missing required properties, a stronger consistency than the account allows, or no partition key on an operation that needs one
401Invalid Authorization header (wrong key, bad token)
404 (substatus 1013)Item or resource doesn't exist; 1013 means a container create is still in progress: keep reading until 200
408A stored procedure, trigger or UDF ran too long
409The id already exists within that partition key value: upsert, or treat as success when idempotent
412ETag mismatch (optimistic concurrency): re-read and retry
413Item over 2 MB
423Another throughput scale operation is running
424Another operation in the same transactional batch failed
449Transient write conflict: safe to retry
503Service or network unavailable: safe to retry

Customer-managed key accounts add substatus 4002 (Cosmos can't reach the key; restore its Key Vault access), 4003 (key deleted; recover it), 4005 (unwrap failed, often after rotation), 4006 (key URL includes a version) and 4009 (Key Vault name doesn't resolve).

TypeScript with Entra ID

import { DefaultAzureCredential } from "@azure/identity";
import { CosmosClient, ErrorResponse } from "@azure/cosmos";

// The identity needs a Cosmos DB data-plane role assignment (Built-in Data Contributor), not an Azure RBAC role.
const client = new CosmosClient({
  endpoint: `https://${process.env.COSMOS_ACCOUNT}.documents.azure.com:443/`,
  aadCredentials: new DefaultAzureCredential(), // the SDK asks for <endpoint>/.default
  connectionPolicy: { retryOptions: { maxRetryAttemptCount: 9, maxWaitTimeInSeconds: 30, fixedRetryIntervalInMilliseconds: 0 } },
});
const orders = client.database("shop").container("orders"); // partition key path: /customerId

type Order = { id: string; customerId: string; total: number };

export async function main(): Promise<void> {
  await orders.items.upsert<Order>({ id: "o-1001", customerId: "c-42", total: 12.5 });

  // Point read: id + partition key, the cheapest operation.
  const { resource } = await orders.item("o-1001", "c-42").read<Order>();
  console.log(resource?.total);

  // Parameterised query scoped to one partition.
  const { resources } = await orders.items
    .query<Order>(
      { query: "SELECT * FROM c WHERE c.customerId = @c AND c.total > @t", parameters: [{ name: "@c", value: "c-42" }, { name: "@t", value: 10 }] },
      { partitionKey: "c-42" },
    )
    .fetchAll();
  console.log(resources.length);

  try {
    await orders.items.create<Order>({ id: "o-1001", customerId: "c-42", total: 1 });
  } catch (e) {
    if (e instanceof ErrorResponse) {
      // code is the HTTP status (409 here); substatus and the activity ID matter for support cases
      console.error(e.code, e.substatus, e.activityId, e.retryAfterInMs);
      if (e.code !== 409) throw e;
    } else throw e;
  }
}

The account needs disableLocalAuth: true and a data-plane role for the identity: reference/cosmos-db/access-and-modeling.md. Create databases and containers in Bicep, not from the app.

Read this document as markdown — the same bytes an agent receives.