hashicorp/terraform · error
Unable to access object
Error message
Unable to access object %q in S3 bucket %q: %w
What it means
Thrown by RemoteClient.Get in the S3 backend when HeadObject errors and the error is neither NoSuchBucket nor *s3types.NotFound. It is the catch-all head-object failure, wrapping the underlying error with %w. Means the bucket is reachable but the HEAD on the specific key failed for another reason.
Solutions
- If using SSE-C, supply the correct customer key configuration on every read.
- If using SSE-KMS, verify the KMS key is enabled and the principal has kms:Decrypt.
- Grant `s3:GetObject` on the state key ARN to the principal.
- Retry on throttling (SlowDown) with exponential backoff.
Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: if SSE-C is in use, ensure the customer key is provided
if c.serverSideEncryption && c.customerEncryptionKey == nil {
return fmt.Errorf("state is SSE-C but no customer key configured")
} Type guard
func isAccessDenied(err error) bool {
var ae smithy.APIError
return errors.As(err, &ae) && ae.ErrorCode()=="AccessDenied"
} Try / catch
headOut, err := c.s3Client.HeadObject(ctx, headInput)
if err != nil {
var ae smithy.APIError
if errors.As(err, &ae) && ae.ErrorCode()=="AccessDenied" { return nil, fmt.Errorf("missing GetObject/KMS Decrypt on %s: %w", c.path, err) }
return nil, err
} Prevention
- Grant s3:GetObject plus kms:Decrypt on the state resources.
- Provide the SSE-C customer key consistently across runs.
- Keep the KMS key policy permissive to the principal.
When it happens
Trigger: HeadObject errors, IsA[*s3types.NoSuchBucket] false, IsA[*s3types.NotFound] false. Causes: 403 AccessDenied on the key (encrypted differently / different SSE-C key), KMS key inaccessible, throttling, or transient 5xx.
Common situations: SSE-C state read with a missing/wrong customer key; SSE-KMS with the KMS key disabled or policy denying decrypt; s3:GetObject permission missing on the key; throttling on a hot prefix.
Related errors
- S3 bucket does not exist. The referenced S3 bucket must…
- Unable to list objects in S3 bucket
- can't delete default state
- error getting object: %#v
- Error unlocking S3 state. Lock ID
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/c75f727b51a26325.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/s3/client.go:146
headInput := &s3.HeadObjectInput{
Bucket: aws.String(c.bucketName),
Key: aws.String(c.path),
}
if c.serverSideEncryption && c.customerEncryptionKey != nil {
headInput.SSECustomerKey = aws.String(base64.StdEncoding.EncodeToString(c.customerEncryptionKey))
headInput.SSECustomerAlgorithm = aws.String(s3EncryptionAlgorithm)
headInput.SSECustomerKeyMD5 = aws.String(c.getSSECustomerKeyMD5())
}
headOut, err := c.s3Client.HeadObject(ctx, headInput)
if err != nil {
switch {
case IsA[*s3types.NoSuchBucket](err):
return nil, fmt.Errorf(errS3NoSuchBucket, c.bucketName, err)
case IsA[*s3types.NotFound](err):
return nil, nil
}
return nil, fmt.Errorf("Unable to access object %q in S3 bucket %q: %w", c.path, c.bucketName, err)
}
// Pre-allocate the full buffer to avoid re-allocations and GC
buf := make([]byte, int(aws.ToInt64(headOut.ContentLength)))
w := manager.NewWriteAtBuffer(buf)
downloadInput := &s3.GetObjectInput{
Bucket: aws.String(c.bucketName),
Key: aws.String(c.path),
}
if c.serverSideEncryption && c.customerEncryptionKey != nil {
downloadInput.SSECustomerKey = aws.String(base64.StdEncoding.EncodeToString(c.customerEncryptionKey))
downloadInput.SSECustomerAlgorithm = aws.String(s3EncryptionAlgorithm)
downloadInput.SSECustomerKeyMD5 = aws.String(c.getSSECustomerKeyMD5())
}
downloader := manager.NewDownloader(c.s3Client)
View on GitHub (pinned to d32a084675)