hashicorp/terraform · error

Unable to list objects in S3 bucket

Error message

Unable to list objects in S3 bucket %q with prefix %q: %w

What it means

Thrown by Backend.Workspaces in the S3 backend when ListObjectsV2 NextPage errors and the error is neither NoSuchBucket nor (in the default-prefix case) an AccessDenied smithy.APIError. It is the catch-all list failure wrapping the underlying error with %w so callers can errors.Is/As it. The state listing operation cannot proceed.

Solutions

  1. Inspect the wrapped error (%w) for `SlowDown`/`Throttling` and retry with backoff.
  2. Grant the principal `s3:ListBucket` on the bucket scoped to the workspace key prefix.
  3. Refresh STS credentials (re-assume role) if the session expired.
  4. Verify KMS key used for bucket is enabled and accessible.
Defensive patterns

Strategy: retry

Validate before calling

// preflight: assert ListBucket permission with a scoped call
_, err := s3Client.ListObjectsV2(ctx, &s3.ListObjectsV2Input{Bucket: aws.String(b), MaxKeys: aws.Int32(1)})
if err != nil { return fmt.Errorf("cannot list bucket %s: %w", b, err) }

Type guard

func isAccessDeniedOrThrottle(err error) bool {
    var ae smithy.APIError
    if errors.As(err, &ae) {
        return ae.ErrorCode()=="AccessDenied" || ae.ErrorCode()=="SlowDown" || ae.ErrorCode()=="Throttling"
    }
    return false
}

Try / catch

page, err := pages.NextPage(ctx)
if err != nil {
    var ae smithy.APIError
    if errors.As(err, &ae) && (ae.ErrorCode()=="SlowDown"||ae.ErrorCode()=="Throttling") { backoff(); continue }
    return err
}

Prevention

When it happens

Trigger: pages.NextPage(ctx) errors, IsA[*s3types.NoSuchBucket] is false, and either the prefix is non-default or the error is not a smithy AccessDenied. Causes: throttling (SlowDown), transient 5xx, iam ListBucket permission missing, KMS decrypt issue on listing, or STS token expired mid-list.

Common situations: Throttling on a hot bucket; expired STS session token; custom workspace_key_prefix with s3:ListBucket scoped to a different prefix; KMS key disabled; region partition mismatch.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/5da3802fa9f74593. Report an issue: GitHub.

Appendix: source

Thrown at internal/backend/remote-state/s3/backend_state.go:78

	}

	wss := []string{backend.DefaultStateName}

	ctx, baselog := baselogging.NewHcLogger(ctx, log)
	ctx = baselogging.RegisterLogger(ctx, baselog)

	pages := s3.NewListObjectsV2Paginator(b.s3Client, params)
	for pages.HasMorePages() {
		page, err := pages.NextPage(ctx)
		if err != nil {
			if IsA[*s3types.NoSuchBucket](err) {
				return nil, diags.Append(fmt.Errorf(errS3NoSuchBucket, b.bucketName, err))
			}
			if foo, ok := As[smithy.APIError](err); b.workspaceKeyPrefix == defaultWorkspaceKeyPrefix && ok && foo.ErrorCode() == "AccessDenied" {
				log.Warn("Unable to list non-default workspaces", "err", err.Error())
				return wss[:1], nil
			}
			return nil, diags.Append(fmt.Errorf("Unable to list objects in S3 bucket %q with prefix %q: %w", b.bucketName, prefix, err))
		}

		for _, obj := range page.Contents {
			ws := b.keyEnv(aws.ToString(obj.Key))
			if ws != "" {
				wss = append(wss, ws)
			}
		}
	}

	sort.Strings(wss[1:])
	return wss, diags
}

func (b *Backend) keyEnv(key string) string {
	prefix := b.workspaceKeyPrefix

	if prefix == "" {

View on GitHub (pinned to d32a084675)