kubernetes/kops · error

error building IAM policy: %v

Error message

error building IAM policy: %v

What it means

PolicyResource.Open wraps any error from pb.BuildAWSPolicy() (the role-level IAM policy builder) as 'error building IAM policy'. This is the outer wrapper for the whole S3/VFS/KMS policy assembly chain described by errors 1350-1356; the inner cause carries the specifics.

Source

Thrown at pkg/model/iam/iam_builder.go:796

		hostedZoneID := fi.ValueOf(b.DNSZone.ZoneID)
		if hostedZoneID == "" {
			// ZoneID is normally populated by DNSZone.Find before this runs. In dry-run modes that
			// skip Find (e.g. `kops get assets`), it may still be empty; fall back to the DNS name
			// so the policy renders. The resulting ARN is not a valid Route53 ARN, but the policy
			// is not applied in that mode.
			hostedZoneID = fi.ValueOf(b.DNSZone.DNSName)
			klog.V(4).Infof("Falling back to DNS name %q for IAM policy because ZoneID is empty", hostedZoneID)
		}
		if hostedZoneID == "" {
			// Dependency analysis failure?
			return nil, fmt.Errorf("DNS ZoneID not set")
		}
		pb.HostedZoneID = hostedZoneID
	}

	policy, err := pb.BuildAWSPolicy()
	if err != nil {
		return nil, fmt.Errorf("error building IAM policy: %v", err)
	}
	if policy == nil {
		return bytes.NewReader([]byte{}), nil
	}
	j, err := policy.AsJSON()
	if err != nil {
		return nil, fmt.Errorf("error building IAM policy: %v", err)
	}
	return bytes.NewReader([]byte(j)), nil
}

func addECRPermissions(p *Policy) {
	// TODO - I think we can just have GetAuthorizationToken here, as we are not
	// TODO - making any API calls except for GetAuthorizationToken.

	// We provide ECR access on the nodes (naturally), but we also provide access on the master.
	// We shouldn't be running lots of pods on the master, but it is perfectly reasonable to run
	// a private logging pod or similar.

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the chained inner error (%v suffix) for the root cause; it will name the failing path or role.
  2. Fix the underlying state store / backupStore / DNS configuration as indicated by that cause.
  3. Validate the whole spec with `kops get cluster -o yaml` and `kops validate cluster` after edits.
  4. Rerun `kops update cluster` to regenerate the IAM policies.
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate store and zone inputs before Open
if _, err := vfs.Context.BuildVfsPath(cluster.Spec.ConfigStore.Base); err != nil {
    return fmt.Errorf("invalid state store: %w", err)
}

Try / catch

r, err := policyResource.Open()
if err != nil {
    var inner = err.Error()
    switch {
    case strings.Contains(inner, "cannot parse VFS path"):
        // fix state store/backupStore URL
    case strings.Contains(inner, "not cluster readable"):
        // switch to s3:// storage
    }
    return fmt.Errorf("open IAM policy resource: %w", err)
}

Prevention

When it happens

Trigger: Any role policy build failure during PolicyResource.Open: NodeRoleAPIServer/Master BuildAWSPolicy returning S3 permission errors, VFS parse failures, unreadable paths, or unsupported writeable path types — all bubbled through PolicyBuilder.BuildAWSPolicy.

Common situations: Invalid state store or etcd backupStore URLs (see 1353-1356); cross-cloud state stores used with AWS IAM generation; corrupted cluster spec after manual edits; kOps version mismatch with the cluster spec format.

Related errors


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