{"record":{"id":"8821f84e27f95c1e","repo":"kubernetes/kops","slug":"arn-q-has-unrecognized-type","errorCode":null,"errorMessage":"arn %q has unrecognized type","messagePattern":"arn %q has unrecognized type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/bootstrap/awsbootstrap/verifier.go","lineNumber":277,"sourceCode":"\tarn := callerIdentity.GetCallerIdentityResult[0].Arn\n\tparts := strings.Split(arn, \":\")\n\tif len(parts) != 6 {\n\t\treturn nil, fmt.Errorf(\"arn %q contains unexpected number of colons\", arn)\n\t}\n\tif parts[0] != \"arn\" {\n\t\treturn nil, fmt.Errorf(\"arn %q doesn't start with \\\"arn:\\\"\", arn)\n\t}\n\tif parts[1] != a.partition {\n\t\treturn nil, fmt.Errorf(\"arn %q not in partion %q\", arn, a.partition)\n\t}\n\tif parts[2] != \"iam\" && parts[2] != \"sts\" {\n\t\treturn nil, fmt.Errorf(\"arn %q has unrecognized service\", arn)\n\t}\n\t// parts[3] is region\n\t// parts[4] is account\n\tresource := strings.Split(parts[5], \"/\")\n\tif resource[0] != \"assumed-role\" {\n\t\treturn nil, fmt.Errorf(\"arn %q has unrecognized type\", arn)\n\t}\n\tif len(resource) < 3 {\n\t\treturn nil, fmt.Errorf(\"arn %q contains too few slashes\", arn)\n\t}\n\tfound := false\n\tfor _, role := range a.opt.NodesRoles {\n\t\tif resource[1] == role {\n\t\t\tfound = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !found {\n\t\treturn nil, fmt.Errorf(\"arn %q does not contain acceptable node role\", arn)\n\t}\n\n\tinstanceID := resource[2]\n\tinstances, err := a.ec2.DescribeInstances(ctx, &ec2.DescribeInstancesInput{\n\t\tInstanceIds: []string{instanceID},","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/bootstrap/awsbootstrap/verifier.go#L259-L295","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: node authenticated with static IAM user credentials, ARN = arn:aws:iam::123456789012:user/kops-admin\n// after: attach the node instance profile so STS returns arn:aws:sts::123456789012:assumed-role/nodes.cluster.example/i-0abc...\nterraform aws_instance { iam_instance_profile = \"nodes.cluster.example\" }","handlingStrategy":"validation","validationCode":"id, err := sts.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})\nif err != nil { return err }\nparts := strings.Split(aws.ToString(id.Arn), \":\")\nres := strings.Split(parts[5], \"/\")\nif len(parts) == 6 && res[0] != \"assumed-role\" {\n    return fmt.Errorf(\"credentials are not from an assumed role session (type %q); use the node instance profile\", res[0])\n}","typeGuard":"func isAssumedRoleARN(arn string) bool {\n\tparts := strings.Split(arn, \":\")\n\tif len(parts) != 6 || (parts[2] != \"iam\" && parts[2] != \"sts\") {\n\t\treturn false\n\t}\n\treturn strings.HasPrefix(parts[5], \"assumed-role/\")\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["aws","iam","sts","bootstrap","arn"],"backgroundTag":"arn-resource-type-mismatch","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}