kubernetes/kops · error

arn %q has unrecognized type

Error message

arn %q has unrecognized type

What it means

During node bootstrap authentication, kOps parses the caller's AWS STS ARN and requires the resource part (parts[5]) to start with "assumed-role/" — i.e. the caller must be an STS assumed role session belonging to a node role. This error is thrown when the ARN is well-formed and in the right account/partition/service, but its resource type is something else, such as "user", "instance", or "federated-user". kOps only trusts nodes whose credentials come from an assumed node role.

Source

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

	arn := callerIdentity.GetCallerIdentityResult[0].Arn
	parts := strings.Split(arn, ":")
	if len(parts) != 6 {
		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},

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Ensure the machine making the bootstrap request authenticates via an EC2 instance profile whose role is listed in NodesRoles (nodes cluster role), not via IAM user keys.
  2. Remove any AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY environment variables on the node that override the instance metadata credentials.
  3. Verify the cluster's node role name matches a.opt.NodesRoles (kops sets "nodes.<clustername>"); recreate the instance with the correct role profile.
  4. If this is a human calling the API, expect this rejection: bootstrap verification is only for nodes with assumed node roles.

Example fix

// before: node authenticated with static IAM user credentials, ARN = arn:aws:iam::123456789012:user/kops-admin
// after: attach the node instance profile so STS returns arn:aws:sts::123456789012:assumed-role/nodes.cluster.example/i-0abc...
terraform aws_instance { iam_instance_profile = "nodes.cluster.example" }
Defensive patterns

Strategy: validation

Validate before calling

id, err := sts.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
if err != nil { return err }
parts := strings.Split(aws.ToString(id.Arn), ":")
res := strings.Split(parts[5], "/")
if len(parts) == 6 && res[0] != "assumed-role" {
    return fmt.Errorf("credentials are not from an assumed role session (type %q); use the node instance profile", res[0])
}

Type guard

func isAssumedRoleARN(arn string) bool {
	parts := strings.Split(arn, ":")
	if len(parts) != 6 || (parts[2] != "iam" && parts[2] != "sts") {
		return false
	}
	return strings.HasPrefix(parts[5], "assumed-role/")
}

Prevention

When it happens

Trigger: verifyCallerIdentity receives a GetCallerIdentityResponse whose ARN resource segment is not "assumed-role" — e.g. the request was authenticated with a long-lived IAM user's credentials, an EC2 instance-profile ARN of type "instance", or an assumed-role ARN in an unexpected format.

Common situations: Running kops/kubectl from a machine using personal IAM user credentials instead of node credentials; nodeup misconfigured to use static AWS keys; a custom/legacy node bootstrap path that signs challenges with user credentials; corporate SSO federated-user ARNs.

Related errors


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