---
cuppy_hub: gcp
cuppy_path: reference/storage/errors.md
cuppy_section: docs
cuppy_doc: 4J28-3C7T
cuppy_doc_uuid: 938d3cf8-c8f8-4837-b73d-caddfd8bf93f
cuppy_permalink: https://cuppy.io/gcp/d/4J28-3C7T
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/gcp/docs/reference/storage/errors
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: b4cdea247b189f5380bcae2920c850d9e28e9b3907d2c8135d743b04bbdaf3b6
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Storage error catalogue

## 1. The three 403s mean three different things

| Reason | Cause | Check | Fix |
|---|---|---|---|
| `forbidden` — "According to access control policy, the current user does not have access" | the allow policy does not grant it | Policy Troubleshooter on the exact permission (`guides/identity/fix-permission-denied.md`) | grant the narrowest predefined role on the **bucket** |
| `insufficientPermissions` | the caller lacks a permission for this specific action | same | same, but note the action, not just the resource |
| `retentionPolicyNotMet` | the object is under a retention policy and the retention date has not passed | read the bucket's retention policy and the object's retention time | **nothing to fix.** This is the control working. Wait, or change a policy that is deliberately hard to change |

`retentionPolicyNotMet` is the one to recognise on sight: a delete loop that retries it will retry forever.

## 2. Authentication, not authorisation

| Reason | Cause | Fix |
|---|---|---|
| 401 `authError` | the credential is the problem: expired, or its format is not recognised | re-mint the credential. **Never** answer this with a role grant |
| 401 `required` | a non-public method was called with no authorization header at all | attach a credential; if this is a browser, you want a signed URL (`reference/storage/cloud-storage-access-control.md` §5) |

## 3. The 400s, and the one that means "your own settings refuse this"

| Reason | Means |
|---|---|
| `badRequest` | "The request cannot be completed based on your current Cloud Storage settings" — the bucket's own configuration refuses it. **Uniform bucket-level access is the usual cause**: an ACL call against a bucket where ACLs are disabled |
| `invalid` | the request violates retention configuration rules or encryption requirements |
| `invalidParameter` | "The value for one of the URL parameters was invalid" |
| `required` | a required URL parameter or body property is missing |

The `badRequest`/uniform-access pairing is worth internalising: client libraries and old scripts set ACLs
routinely, and on a correctly configured bucket every one of those calls is a 400, not a 403.

## 4. Conflict, precondition and rate

| Status | Reason | What to do |
|---|---|---|
| 404 | `notFound` | resource or API method not found — check both. A wrong API path returns the same reason as a missing object |
| 409 | `conflict` | a concurrent-modification conflict. **The page tells you to retry the request** |
| 412 | `conditionNotMet` | a precondition you sent (`ifGenerationMatch`, `ifMetagenerationMatch`) was not satisfied. Re-read, then retry with the new generation. **Do not strip the precondition** — it is the thing preventing a lost update |
| 429 | `rateLimitExceeded` | "A Cloud Storage JSON API usage limit was exceeded". Back off; read the live quota (`reference/overview/quotas-and-limits-model.md`) |

## 5. The 5xx rule, in the vendor's own words

500 and 503 `backendError`, and 504: **"retry the request using truncated exponential backoff"**. That is the
documented instruction, and it is the same for all three statuses. A client that retries immediately, or that
treats a 503 as fatal, is wrong in both directions.

## 6. Where to go next

- the settings behind §1 and §3: `reference/storage/cloud-storage-access-control.md`
- the identity side of every 403: `guides/identity/fix-permission-denied.md`
- the cross-cloud equivalents (S3's `AccessDenied` and `SlowDown`, Blob's `AuthorizationFailure` and
  `ServerBusy`): `guides/parity/storage.md`


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 91 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/gcp/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
