## TL;DR

The agent's IAM role can list the billing bucket but cannot read the CUR manifest file, so the billing pipeline stops at the first object fetch. Add s3:GetObject on the billing bucket's CUR prefix to the role policy (and s3:ListBucket on the bucket), then retry. Reading the manifest is the entry point to the whole CUR dataset.

## Error

```text
"AccessDenied: s3:GetObject on the CUR manifest"  -  agent's billing role missing read
```

## Steps

1. Confirm the denial is on s3:GetObject for the manifest path. Expected: the error names the action and the manifest key.
2. Open the agent role's policy and check for s3:GetObject on the billing bucket. Expected: the read permission is missing or scoped to the wrong prefix.
3. Add s3:GetObject on the CUR prefix and s3:ListBucket on the bucket. Expected: the policy covers both list and read.
4. Retry the agent's CUR fetch. Expected: the manifest downloads and the pipeline proceeds.
5. If the manifest is KMS-encrypted, also grant kms:Decrypt on the key (a separate error will name it). Expected: encrypted manifests decrypt.

## When to use

- A cost agent gets AccessDenied on the CUR manifest.
- The billing pipeline fails at the first S3 read.
- A new role was created for the billing agent.

## When not to use

- The error is KMS AccessDenied (a key-grant problem).
- The bucket policy explicitly denies the role (a bucket-policy problem).
- The manifest file does not exist (a CUR delivery problem).

## Tool compatibility

AWS S3, IAM, and Cost and Usage Reports (current 2026 releases).

### Variant phrasings

### "access denied" reading the cur manifest

Grant s3:GetObject on the CUR prefix.

### billing agent can't fetch the cur files

The role needs list plus read on the billing bucket.

### new billing role fails on first s3 read

Scope the read grant to the CUR prefix.

## Why it happens

CUR pipelines need two S3 permissions that are often granted separately: ListBucket to find the manifest and GetObject to read it. Teams grant the list (the pipeline starts) but forget the read (the pipeline dies on the first fetch). The manifest is also the canary: if the role cannot read it, it cannot read any CUR data file either.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_CVNi1xFLtpbfDFq2QD8Fww
