hashicorp/terraform · error

bucket not exists

Error message

bucket %s not exists

What it means

Returned by getBucket() when the COS SDK returns a nil response pointer from Bucket.Get (list). On the list path the backend interprets a nil response as 'bucket not exists', which is an imperfect mapping — the real cause may be transport failure rather than absence.

Solutions

  1. Look at DEBUG line `getBucket <bucket>/<prefix>: error:` for the underlying SDK error.
  2. Confirm the bucket name includes the APPID suffix and the region matches.
  3. Grant `cos:GetBucket` (list) permission to the principal.
  4. Verify network reachability to COS and retry.

Example fix

// before: bucket name without APPID
backend "cos" { bucket="tf-state"; region="ap-guangzhou" }
// after: append APPID
backend "cos" { bucket="tf-state-1250000000"; region="ap-guangzhou" }
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: validate the bucket name (with APPID) and list permission
func bucketAccessible(ctx context.Context, client *cos.Client, bucket string) error {
    _, rsp, err := client.Bucket.Get(ctx, &cos.BucketGetOptions{Prefix: ""})
    if rsp == nil { return fmt.Errorf("could not reach COS for bucket %s: %w", bucket, err) }
    defer rsp.Body.Close()
    if rsp.StatusCode == 404 { return fmt.Errorf("bucket %s not found (check name-APPID and region)", bucket) }
    if rsp.StatusCode == 403 { return fmt.Errorf("principal lacks cos:GetBucket on %s", bucket) }
    return nil
}

Type guard

func looksLikeCOSBucketName(name string) bool {
    // <3-63 chars, lowercase, digits, hyphen>, ends with -<10 digit APPID>
    matched, _ := regexp.MatchString(`^[a-z0-9-]{3,63}-[0-9]{10}$`, name)
    return matched
}

Try / catch

// Distinguish 404 (genuine absence) from nil-response (transport)
if rsp == nil { /* transport: retry */ } else if rsp.StatusCode == 404 { /* real absence: fix config */ }

Prevention

When it happens

Trigger: c.cosClient.Bucket.Get(...) returns (nil, rsp, err). Network failure, invalid endpoint, bad credentials, or the bucket genuinely being unreachable all collapse into this single message.

Common situations: Wrong `region` for the bucket name; APPID not embedded in the bucket name (`<bucket>-<appid>`); credentials lack `cos:GetBucket`; no outbound connectivity; transient DNS failure.

Related errors


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

Appendix: source

Thrown at internal/backend/remote-state/cos/client.go:285

	log.Printf("[DEBUG] deleteObject %s: code: %d, error: %v", cosFile, rsp.StatusCode, err)
	if rsp.StatusCode == 404 {
		return nil
	}

	if err != nil {
		return fmt.Errorf("failed to delete file %v: %v", cosFile, err)
	}

	return nil
}

// getBucket list bucket by prefix
func (c *remoteClient) getBucket(prefix string) (obs []cos.Object, err error) {
	fs, rsp, err := c.cosClient.Bucket.Get(c.cosContext, &cos.BucketGetOptions{Prefix: prefix})
	if rsp == nil {
		log.Printf("[DEBUG] getBucket %s/%s: error: %v", c.bucket, prefix, err)
		err = fmt.Errorf("bucket %s not exists", c.bucket)
		return
	}
	defer rsp.Body.Close()

	log.Printf("[DEBUG] getBucket %s/%s: code: %d, error: %v", c.bucket, prefix, rsp.StatusCode, err)
	if rsp.StatusCode == 404 {
		err = fmt.Errorf("bucket %s not exists", c.bucket)
		return
	}

	if err != nil {
		return
	}

	return fs.Contents, nil
}

// putBucket create cos bucket

View on GitHub (pinned to d32a084675)