hashicorp/terraform · error

error getting bucket: %#v

Error message

error getting bucket: %#v

What it means

Thrown by Workspaces() when ossClient.Bucket(bucketName) fails. This is the SDK call that resolves a Bucket handle for the configured OSS bucket; failure indicates the OSS client itself rejected the configuration or could not resolve the bucket metadata.

Solutions

  1. Validate the bucket name (lowercase, 3–63 chars, DNS-compatible) in the backend config.
  2. Ensure access_key_id, access_key_secret, and (if using STS) security_token / assumed-role are all provided.
  3. Confirm endpoint and region match the bucket's actual region.
  4. Re-run after refreshing credentials if this followed an STS expiry.
Defensive patterns

Strategy: validation

Validate before calling

// Validate the bucket name format before relying on the SDK.
import "regexp"
var bucketRe = regexp.MustCompile(`^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$`)
if !bucketRe.MatchString(bucketName) { return fmt.Errorf("invalid OSS bucket name %q", bucketName) }

Type guard

func validBucketName(name string) bool {
    if len(name) < 3 || len(name) > 63 { return false }
    match, _ := regexp.MatchString(`^[a-z0-9][a-z0-9.-]*[a-z0-9]$`, name)
    return match
}

Prevention

When it happens

Trigger: ossClient.Bucket returns an error during workspace enumeration — typically an invalid bucket name format, missing client configuration, or an SDK initialization defect surfacing here.

Common situations: Malformed bucket name (uppercase, underscores, too long), access_key_id / access_key_secret / security_token not set, region/endpoint misconfiguration, or running with stale credentials during STS refresh.

Related errors


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

Appendix: source

Thrown at internal/backend/remote-state/oss/backend_state.go:61

	}
	if b.otsEndpoint != "" && b.otsTable != "" {
		_, err := b.otsClient.DescribeTable(&tablestore.DescribeTableRequest{
			TableName: b.otsTable,
		})
		if err != nil {
			return client, fmt.Errorf("error describing table store %s: %#v", b.otsTable, err)
		}
	}

	return client, nil
}

func (b *Backend) Workspaces() ([]string, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics

	bucket, err := b.ossClient.Bucket(b.bucketName)
	if err != nil {
		return []string{""}, diags.Append(fmt.Errorf("error getting bucket: %#v", err))
	}

	var options []oss.Option
	options = append(options, oss.Prefix(b.statePrefix+"/"), oss.MaxKeys(1000))
	resp, err := bucket.ListObjects(options...)
	if err != nil {
		return nil, diags.Append(err)
	}

	result := []string{backend.DefaultStateName}
	prefix := b.statePrefix
	lastObj := ""
	for {
		for _, obj := range resp.Objects {
			// we have 3 parts, the state prefix, the workspace name, and the state file: <prefix>/<worksapce-name>/<key>
			if path.Join(b.statePrefix, b.stateKey) == obj.Key {
				// filter the default workspace
				continue

View on GitHub (pinned to d32a084675)