kubernetes/kops · error

error inline policy: %w

Error message

error inline policy: %w

What it means

When building IAM for ServiceAccountExternalPermissions entries, an inline IAM policy JSON supplied via spec.iam.serviceAccountExternalPermissions[].aws.inlinePolicy is parsed by buildPolicy (iam.ParseStatements). If the string is not valid IAM policy JSON (bad syntax, wrong types, empty statement), the parse error is wrapped as "error inline policy".

Source

Thrown at pkg/model/awsmodel/iam.go:140

			return err
		}

		iamName := b.IAMName(igRole)
		if err := b.buildIAMTasks(role, iamName, c, false); err != nil {
			return err
		}
	}

	iamSpec := b.Cluster.Spec.IAM
	if iamSpec != nil {
		for _, sa := range iamSpec.ServiceAccountExternalPermissions {
			var p *iam.Policy
			aws := sa.AWS
			if aws.InlinePolicy != "" {
				bp, err := b.buildPolicy(aws.InlinePolicy)
				p = bp
				if err != nil {
					return fmt.Errorf("error inline policy: %w", err)
				}
			}
			serviceAccount := &iam.GenericServiceAccount{
				NamespacedName: types.NamespacedName{
					Name:      sa.Name,
					Namespace: sa.Namespace,
				},
				Policy: p,
			}
			iamRole, err := b.BuildServiceAccountRoleTasks(serviceAccount, c)
			if err != nil {
				return fmt.Errorf("error building service account role tasks: %w", err)
			}
			if len(aws.PolicyARNs) > 0 {
				name := "external-" + fi.ValueOf(iamRole.Name)
				externalPolicies := aws.PolicyARNs
				c.AddTask(&awstasks.IAMRolePolicy{
					Name:             new(name),

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Validate the inlinePolicy string as JSON with `echo '<policy>' | jq .` and fix syntax errors.
  2. Ensure Statement is an array and each statement has Effect/Action/Resource of the correct types.
  3. If templating, render the template and check for unexpanded placeholders before applying.

Example fix

// before
aws:
  inlinePolicy: '{"Version":"2012-10-17","Statement":{"Effect":"Allow","Action":"s3:*","Resource":"*"}}'
// after
aws:
  inlinePolicy: '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:*","Resource":"*"}]}'
Defensive patterns

Strategy: validation

Validate before calling

if inlinePolicy != "" {
	var doc map[string]interface{}
	if err := json.Unmarshal([]byte(inlinePolicy), &doc); err != nil {
		return fmt.Errorf("inlinePolicy is not valid JSON: %w", err)
	}
	if _, ok := doc["Statement"]; !ok {
		return fmt.Errorf("inlinePolicy missing Statement")
	}
}

Try / catch

if err := runKopsUpdate(); err != nil {
	var parseErr *json.SyntaxError
	if errors.As(err, &parseErr) && strings.Contains(err.Error(), "error inline policy") {
		// fix inlinePolicy JSON before retrying
	}
	return err
}

Prevention

When it happens

Trigger: `kops update cluster` when a ServiceAccountExternalPermissions entry has aws.inlinePolicy set to invalid JSON, e.g. YAML-quoted template that never got rendered, trailing commas, or a Statement that is an object instead of an array.

Common situations: Hand-writing IAM policy JSON in the cluster spec; templating the policy with envsubst/Helm and leaving unexpanded placeholders; copy-pasting policies that use comments or single quotes.

Related errors


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