kubernetes/kops · error

arn %q contains too few slashes

Error message

arn %q contains too few slashes

What it means

After confirming the ARN resource starts with "assumed-role", kOps splits it and requires at least three slash-separated segments: "assumed-role", the role name, and the session name (which kOps uses as the EC2 instance ID). This error is thrown when an assumed-role ARN lacks the session/instance-ID segment, so the instance cannot be identified.

Source

Thrown at pkg/bootstrap/awsbootstrap/verifier.go:280

		return nil, fmt.Errorf("arn %q contains unexpected number of colons", arn)
	}
	if parts[0] != "arn" {
		return nil, fmt.Errorf("arn %q doesn't start with \"arn:\"", arn)
	}
	if parts[1] != a.partition {
		return nil, fmt.Errorf("arn %q not in partion %q", arn, a.partition)
	}
	if parts[2] != "iam" && parts[2] != "sts" {
		return nil, fmt.Errorf("arn %q has unrecognized service", arn)
	}
	// parts[3] is region
	// parts[4] is account
	resource := strings.Split(parts[5], "/")
	if resource[0] != "assumed-role" {
		return nil, fmt.Errorf("arn %q has unrecognized type", arn)
	}
	if len(resource) < 3 {
		return nil, fmt.Errorf("arn %q contains too few slashes", arn)
	}
	found := false
	for _, role := range a.opt.NodesRoles {
		if resource[1] == role {
			found = true
			break
		}
	}
	if !found {
		return nil, fmt.Errorf("arn %q does not contain acceptable node role", arn)
	}

	instanceID := resource[2]
	instances, err := a.ec2.DescribeInstances(ctx, &ec2.DescribeInstancesInput{
		InstanceIds: []string{instanceID},
	})
	if err != nil {
		return nil, fmt.Errorf("describing instance for arn %q", arn)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Ensure nodeup obtains credentials via the instance metadata service (IMDS) so the session name is the instance ID, rather than calling AssumeRole itself.
  2. If assuming the node role manually for testing, set RoleSessionName to the EC2 instance ID: aws sts assume-role --role-arn ... --role-session-name i-0abc123.
  3. Check nodeup/kOps version consistency between control plane and nodes; upgrade outdated nodeup.
  4. Confirm nothing in the environment proxies or rewrites bootstrap requests with different credentials.

Example fix

// before (custom token generator)
sts.AssumeRole(&sts.AssumeRoleInput{RoleArn: r, RoleSessionName: aws.String("tmp")})
// after
sts.AssumeRole(&sts.AssumeRoleInput{RoleArn: r, RoleSessionName: aws.String(instanceID)})
Defensive patterns

Strategy: validation

Validate before calling

res := strings.Split(strings.Split(arn, ":")[5], "/")
if len(res) < 3 {
    return fmt.Errorf("assumed-role ARN %q lacks session/instance-id segment; set RoleSessionName to the instance ID", arn)
}

Type guard

func arnHasInstanceID(arn string) (string, bool) {
	res := strings.Split(strings.Split(arn, ":")[5], "/")
	if len(res) < 3 || !strings.HasPrefix(res[2], "i-") {
		return "", false
	}
	return res[2], true
}

Prevention

When it happens

Trigger: verifyCallerIdentity receives an ARN like arn:aws:sts::123:assumed-role/nodes.cluster (only two resource segments, no trailing "/<session>") — i.e. an AssumeRole session was created without a meaningful RoleSessionName or the session name itself contains no instance ID.

Common situations: Custom code calling sts:AssumeRole on the node role without setting RoleSessionName to the instance ID; older kOps nodeup versions or third-party tools assuming the role with a non-instance-ID session name; hand-crafted tokens used against the challenge endpoint.

Related errors


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