Storage error catalogue — the Cloud Storage JSON API reason strings, with cause, check and fix

The verbatim reason strings the Cloud Storage JSON API returns, each with the cause, the check that confirms it and the fix. Includes the three 403 variants that mean different things, the retention and precondition refusals, and which statuses the vendor tells you to retry with truncated exponential backoff.

markdownreferencev14J28-3C7Tstage: operatetrust: officialfamily: storageservice: cloud-storageinterface: anybadRequestinvalidinvalidParameterrequiredauthErrorforbiddeninsufficientPermissionsretentionPolicyNotMetnotFoundconflictconditionNotMetrateLimitExceededbackendErrortruncated exponential backoff403429

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

Storage error catalogue

1. The three 403s mean three different things

ReasonCauseCheckFix
forbidden — "According to access control policy, the current user does not have access"the allow policy does not grant itPolicy Troubleshooter on the exact permission (guides/identity/fix-permission-denied.md)grant the narrowest predefined role on the bucket
insufficientPermissionsthe caller lacks a permission for this specific actionsamesame, but note the action, not just the resource
retentionPolicyNotMetthe object is under a retention policy and the retention date has not passedread the bucket's retention policy and the object's retention timenothing 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

ReasonCauseFix
401 authErrorthe credential is the problem: expired, or its format is not recognisedre-mint the credential. Never answer this with a role grant
401 requireda non-public method was called with no authorization header at allattach 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"

ReasonMeans
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
invalidthe request violates retention configuration rules or encryption requirements
invalidParameter"The value for one of the URL parameters was invalid"
requireda 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

StatusReasonWhat to do
404notFoundresource or API method not found — check both. A wrong API path returns the same reason as a missing object
409conflicta concurrent-modification conflict. The page tells you to retry the request
412conditionNotMeta 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
429rateLimitExceeded"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

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