hashicorp/terraform · error
S3 bucket %q does not exist. The referenced S3 bucket must
Error message
S3 bucket %q does not exist. The referenced S3 bucket must have been previously created. If the S3 bucket was created within the last minute, please wait for a minute or two and try again. Error: %s
What it means
Thrown in RemoteClient.get() (s3/client.go:142) when the HeadObject call returns *s3types.NoSuchBucket. The configured bucket does not exist (or is invisible to the caller's credentials in the resolved region) at state-read time. Same multi-line errS3NoSuchBucket message used elsewhere in the S3 backend.
Source
Thrown at internal/backend/remote-state/s3/client.go:142
return payload, diags.Append(err)
}
func (c *RemoteClient) get(ctx context.Context) (*remote.Payload, error) {
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())View on GitHub (pinned to c9def3e214)
Solutions
- Verify the bucket exists and is in the configured region (`aws s3api head-bucket --bucket <name>`).
- Confirm caller identity matches the owning account (`aws sts get-caller-identity`).
- Correct the bucket/region in the backend config or recreate the bucket.
- Wait one to two minutes if it was just created, then retry.
Example fix
// verify before reading state // aws s3api head-bucket --bucket mycorp-tfstate --region us-west-2
Defensive patterns
Strategy: validation
Validate before calling
// Confirm bucket existence + region before reading state
// out, err := s3Client.HeadBucket(ctx, &s3.HeadBucketInput{Bucket: aws.String(bucket)})
// if err != nil { return fmt.Errorf("bucket missing: %w", err) } Prevention
- Gate init on a `aws s3api head-bucket` check.
- Lock the backend config so the bucket/region cannot drift.
- Confirm the assumed role lands in the owning account.
When it happens
Trigger: Bucket deleted between init and a later read; wrong bucket name/region in config; AssumeRole to the wrong account; bucket created <1 min ago and not yet consistent.
Common situations: Bucket recreated/renamed without updating the backend config; region mismatch; cross-account access misconfigured; credentials silently switched accounts.
Related errors
- S3 bucket %q does not exist. The referenced S3 bucket must
- missing state name
- invalid md5
- bucket %s not exists
- Failed to configure: %s
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/0c7f841682ec2f66.
Report an issue: GitHub.