# Access denied. Bucket 'my-bucket' has uniform bucket-level access enabled, so object-level ACLs cannot be set. Use bucket-level IAM permissions instead.

- **ID:** `cloud/gcp-cloud-storage-bucket-policy-only-upload-fails`
- **Domain:** cloud
- **Category:** config_error
- **Verification:** ai_generated
- **Fix Rate:** 90%

## Root Cause

When uniform bucket-level access is enabled, Cloud Storage rejects any request that includes an object ACL (e.g., `x-goog-acl: public-read` header) because all permissions must be managed via IAM at the bucket level.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| Google Cloud Storage (JSON API v1) | active | — | — |
| gsutil 5.28 | active | — | — |
| Google Cloud SDK 474.0.0 | active | — | — |

## Workarounds

1. **Remove the ACL header from the upload request and instead grant public access via IAM: `gsutil iam ch allUsers:objectViewer gs://my-bucket`** (95% success)
   ```
   Remove the ACL header from the upload request and instead grant public access via IAM: `gsutil iam ch allUsers:objectViewer gs://my-bucket`
   ```
2. **If object-level ACLs are required, disable uniform bucket-level access: `gsutil bucket update gs://my-bucket --no-uniform-bucket-level-access`** (80% success)
   ```
   If object-level ACLs are required, disable uniform bucket-level access: `gsutil bucket update gs://my-bucket --no-uniform-bucket-level-access`
   ```

## Dead Ends

- **** — The error is about ACLs, not object existence; checking existence does not resolve the permission conflict. (90% fail)
- **** — Fine-grained access is the opposite of uniform; enabling it would allow ACLs but may break existing IAM policies. (50% fail)
- **** — The service account may have permissions but the request itself includes an ACL header that is rejected. (70% fail)
