kubernetes/kops · error

HeadBucket on %q did not return a bucket region

Error message

HeadBucket on %q did not return a bucket region

What it means

Returned by bucketLocationViaHead when a HeadBucket call succeeds (or fails with a redirect) but the response contains no bucket region — neither the BucketRegion field nor the x-amz-bucket-region header. The bucket may be unreachable, the credentials wrong, or an atypical S3-compatible endpoint that omits region headers, leaving region resolution impossible.

Source

Thrown at util/pkg/vfs/s3context.go:300

}

// bucketLocationViaHead resolves the region for a bucket using HeadBucket.
// GetBucketLocation does not work for cross-account buckets queried from a different region.
// HeadBucket can be called against any region in the partition: on success the response carries
// BucketRegion, and on a cross-region failure (e.g. 301 PermanentRedirect) S3 still sets the
// x-amz-bucket-region response header, which we recover from the wrapped response error.
func bucketLocationViaHead(ctx context.Context, s3Client *s3.Client, bucket string) (string, error) {
	ctx, span := tracer.Start(ctx, "bucketLocationViaHead")
	defer span.End()

	out, err := s3Client.HeadBucket(ctx, &s3.HeadBucketInput{
		Bucket: aws.String(bucket),
	})
	if err == nil {
		if out.BucketRegion != nil && *out.BucketRegion != "" {
			return *out.BucketRegion, nil
		}
		return "", fmt.Errorf("HeadBucket on %q did not return a bucket region", bucket)
	}

	var respErr *smithyhttp.ResponseError
	if errors.As(err, &respErr) && respErr.Response != nil && respErr.Response.Response != nil {
		if bucketRegion := respErr.Response.Header.Get("x-amz-bucket-region"); bucketRegion != "" {
			return bucketRegion, nil
		}
	}
	return "", fmt.Errorf("getting location for bucket %q: %w", bucket, err)
}

// isRunningOnEC2 determines if we could be running on EC2.
// It is used to avoid a call to the metadata service to get the current region,
// because that call is slow if not running on EC2
func isRunningOnEC2(ctx context.Context) (bool, error) {
	if runtime.GOOS == "linux" {
		// Approach based on https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html
		productUUID, err := os.ReadFile("/sys/devices/virtual/dmi/id/product_uuid")

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Retry the HeadBucket call — transient intermediary responses sometimes omit the header
  2. Verify the bucket exists and credentials allow HeadBucket on it
  3. For S3-compatible endpoints, ensure the endpoint actually implements HeadBucket region reporting or configure the region explicitly
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at util/pkg/vfs/s3context.go:300 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/1cf831c4bb163e0c. Report an issue: GitHub.