# Cost Query Error Handling Detailed error handling reference for the Cost Management Query API. ## HTTP Status Codes | Status | Error | Cause | Remediation | |--------|-------|-------|-------------| | 400 | `BadRequest` | Invalid request body, unsupported dimension, date range exceeds limits, malformed filter expression. | Validate request body against [request-body-schema.md](request-body-schema.md). Check dimension compatibility in [dimensions-by-scope.md](dimensions-by-scope.md). | | 401 | `Unauthorized` | Missing or expired authentication token. | Re-authenticate with `az login` or refresh the bearer token. | | 403 | `Forbidden` | Insufficient permissions on the target scope. User lacks Cost Management Reader or equivalent role. | Assign `Cost Management Reader` or `Cost Management Contributor` role on the scope. | | 404 | `NotFound` | Scope does not exist, subscription not found, or resource group does not exist. | Verify the scope URL. Confirm the subscription ID and resource group name are correct. | | 429 | `TooManyRequests` | Rate limit exceeded. QPU, entity, or tenant throttling triggered. | Check all `x-ms-ratelimit-microsoft.costmanagement-*-retry-after` headers (`qpu`, `entity`, `tenant`). Wait for the **longest** value before retrying. | | 503 | `ServiceUnavailable` | Cost Management service is temporarily unavailable. | Check [Azure Status](https://status.azure.com) for service health. | ## Common Error Scenarios | Error Message / Scenario | Cause | Remediation | |--------------------------|-------|-------------| | "Agreement type X does not support Y scope" | Scope type is incompatible with the account's agreement type. | Use a compatible scope. EA accounts cannot use Invoice Section scope; MOSP accounts cannot use Department scope. | | "Dimension Z is not valid for scope" | The requested dimension is not available for the current scope and agreement type combination. | Check [dimensions-by-scope.md](dimensions-by-scope.md) for valid dimensions. | | "SubscriptionName filter without SubscriptionId" | EA + Management Group scope: filtering by `SubscriptionName` without also filtering by `SubscriptionId`. | Add a `SubscriptionId` filter alongside the `SubscriptionName` filter. See [guardrails.md](guardrails.md). | | Date range exceeds granularity limit | `Daily` range > 31 days or `Monthly`/`None` range > 12 months. | System auto-truncates `from` date. To avoid silent truncation, ensure range is within limits. | | Date range exceeds absolute limit (37 months) | `from` to `to` spans more than 37 months. | Reduce the date range to 37 months or less. Split into multiple queries if needed. | | "Request body is null or invalid" | Missing or malformed JSON in the request body. | Validate JSON syntax. Ensure `type`, `timeframe`, and `dataset` fields are present. | | Invalid filter structure | `and`/`or` has fewer than 2 child expressions, or `not` has more than 1. | Ensure `and`/`or` contain 2+ children. Use `not` with exactly 1 child. For single conditions, use the filter directly without a logical wrapper. | | "The query usage is not supported for the scope" | The query type (e.g., `AmortizedCost`) is not supported at the given scope. | Try a different scope or query type. Not all scopes support all report types. | | `BillingSubscriptionNotFound` | The subscription ID in the scope URL is invalid or not associated with the billing account. | Verify the subscription ID exists and is active. Check that it belongs to the expected billing account. | ## Retry Strategy | Status | Retry? | Strategy | |--------|--------|----------| | 429 | ✅ Yes | Check the response for all `x-ms-ratelimit-microsoft.costmanagement-*-retry-after` headers (`qpu-retry-after`, `entity-retry-after`, `tenant-retry-after`). Take the **longest** value and **do NOT retry until that duration has fully elapsed.** Maximum 3 retries. | | 400 | ❌ No | Fix the request. Review error message for specific field or validation issue. | | 401 | ❌ No | Re-authenticate. Token has expired or is missing. | | 403 | ❌ No | Fix permissions. Request appropriate RBAC role assignment on the scope. | | 404 | ❌ No | Fix the scope URL. Verify resource exists. | | 503 | ❌ No | Do not retry. Check [Azure Status](https://status.azure.com) for service health. | | 5xx (other) | ❌ No | Do not retry. Investigate the error and check service health. | > ⚠️ **Warning:** Do not retry any errors except 429. All other errors indicate issues that must be fixed before re-attempting the request. ## Error Response Structure All error responses follow a consistent JSON structure: ```json { "error": { "code": "", "message": "", "details": [ { "code": "", "message": "" } ] } } ``` | Field | Description | |-------|-------------| | `error.code` | Machine-readable error code (e.g., `BadRequest`, `BillingSubscriptionNotFound`). | | `error.message` | Human-readable description of the error. | | `error.details` | Optional array of additional detail objects with more specific error information. |