kubernetes/kops · error

error checking GCS bucket ACL for gs://%s for %s: %v

Error message

error checking GCS bucket ACL for gs://%s for %s: %v

What it means

StorageBucketAcl.Find wraps a failed cloud.google.com/go/storage Bucket ACL List call. kOps lists the bucket's ACL rules to compare desired vs actual state; any error other than NotFound (which is treated as "no ACL yet") is wrapped with the bucket and entity for context.

Source

Thrown at upup/pkg/fi/cloudup/gcetasks/storagebucketacl.go:60

var _ fi.CompareWithID = (*StorageBucketAcl)(nil)

func (e *StorageBucketAcl) CompareWithID() *string {
	return e.Name
}

func (e *StorageBucketAcl) Find(c *fi.CloudupContext) (*StorageBucketAcl, error) {
	cloud := c.T.Cloud.(gce.GCECloud)

	bucket := fi.ValueOf(e.Bucket)
	entity := fi.ValueOf(e.Entity)

	klog.V(2).Infof("Checking GCS bucket ACL for gs://%s for %s", bucket, entity)
	rules, err := cloud.Storage().Bucket(bucket).ACL().List(context.TODO())
	if err != nil {
		if gce.IsNotFound(err) {
			return nil, nil
		}
		return nil, fmt.Errorf("error checking GCS bucket ACL for gs://%s for %s: %v", bucket, entity, err)
	}

	for _, r := range rules {
		if string(r.Entity) != entity {
			continue
		}

		foundEntity := string(r.Entity)
		foundRole := string(r.Role)

		actual := &StorageBucketAcl{}
		actual.Name = e.Name
		actual.Bucket = e.Bucket
		actual.Entity = &foundEntity

		actual.Role = &foundRole

		// Ignore "system" fields

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped %v error: 403 => grant the caller storage.buckets.get / roles/storage.admin on the bucket's project; 404 => the bucket name is wrong or the bucket was deleted.
  2. Confirm the bucket exists and is in the project kOps authenticates to: `gcloud storage buckets describe gs://<bucket>`.
  3. If the bucket belongs to a different project, grant cross-project access or point the spec at the right bucket.
  4. Retry after transient network/5xx errors.
Defensive patterns

Strategy: retry

Validate before calling

cmd := exec.Command("gcloud", "storage", "buckets", "describe", "gs://"+bucket, "--format=value(name)")
if err := cmd.Run(); err != nil {
    return fmt.Errorf("bucket %q inaccessible with current credentials: %w", bucket, err)
}

Try / catch

if err := kopsUpdate(); err != nil {
    if strings.Contains(err.Error(), "error checking GCS bucket ACL") {
        if strings.Contains(err.Error(), "403") {
            log.Print("grant storage.buckets.get on the bucket's project")
        } else if isTransient(err) {
            retryWithBackoff()
        }
    }
    return err
}

Prevention

When it happens

Trigger: cloud.Storage().Bucket(bucket).ACL().List(ctx) returns a non-nil, non-NotFound error during the Find phase of `kops update cluster`.

Common situations: The bucket is owned by another project and the kOps credentials lack storage.buckets.get; the bucket name refers to a bucket that doesn't exist (in a way not surfaced as NotFound, e.g. permission-masked 403); request failed due to network/proxy issues; storage.buckets.get denied by org policy on a cross-project bucket.

Related errors


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