# botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

- **ID:** `llm/llamaindex-index-persistence-s3`
- **Domain:** llm
- **Category:** auth_error
- **Error Code:** `AccessDenied`
- **Verification:** ai_generated
- **Fix Rate:** 90%

## Root Cause

Insufficient IAM permissions for the S3 bucket when LlamaIndex attempts to persist index data to cloud storage.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| llama-index 0.10.0 | active | — | — |
| llama-index 0.10.1 | active | — | — |
| boto3 1.34.0 | active | — | — |

## Workarounds

1. **Update IAM policy to include s3:PutObject and s3:PutObjectAcl permissions for the specific bucket: {"Effect": "Allow", "Action": ["s3:PutObject"], "Resource": "arn:aws:s3:::your-bucket/*"}** (95% success)
   ```
   Update IAM policy to include s3:PutObject and s3:PutObjectAcl permissions for the specific bucket: {"Effect": "Allow", "Action": ["s3:PutObject"], "Resource": "arn:aws:s3:::your-bucket/*"}
   ```
2. **Switch to local persistence: storage_context.persist(persist_dir='./storage') instead of S3** (90% success)
   ```
   Switch to local persistence: storage_context.persist(persist_dir='./storage') instead of S3
   ```

## Dead Ends

- **Setting AWS region to us-east-1 in boto3 config** — Region mismatch doesn't cause AccessDenied; it's a permission issue, not location. (95% fail)
- **Adding public access to S3 bucket** — Public access violates security best practices and doesn't address missing IAM policy. (85% fail)
