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
- 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.
- Remove any AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY environment variables on the node that override the instance metadata credentials.
- Verify the cluster's node role name matches a.opt.NodesRoles (kops sets "nodes.<clustername>"); recreate the instance with the correct role profile.
- 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
- Never place long-lived IAM user keys on cluster nodes; rely on instance profiles/IMDS.
- Verify with `aws sts get-caller-identity` on the node that the ARN contains assumed-role before attempting bootstrap.
- Keep AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY unset on node hosts.
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
- arn %q contains too few slashes
- arn %q does not contain acceptable node role
- getting AWS STS url: %w
- building AWS STS presigned request: %w
- parsing STS request URL: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/8821f84e27f95c1e.
Report an issue: GitHub.