{"record":{"id":"6646d4af08852946","repo":"kubernetes/kops","slug":"arn-q-does-not-contain-acceptable-node-role","errorCode":null,"errorMessage":"arn %q does not contain acceptable node role","messagePattern":"arn %q does not contain acceptable node role","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/bootstrap/awsbootstrap/verifier.go","lineNumber":290,"sourceCode":"\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},\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"describing instance for arn %q\", arn)\n\t}\n\n\tif len(instances.Reservations) <= 0 || len(instances.Reservations[0].Instances) <= 0 {\n\t\treturn nil, fmt.Errorf(\"missing instance id: %s\", instanceID)\n\t}\n\tif len(instances.Reservations[0].Instances) > 1 {\n\t\treturn nil, fmt.Errorf(\"found multiple instances with instance id: %s\", instanceID)\n\t}\n\n\tinstance := instances.Reservations[0].Instances[0]","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/bootstrap/awsbootstrap/verifier.go#L272-L308","documentation":"kOps only accepts bootstrap requests from sessions of the configured node roles (a.opt.NodesRoles). After extracting the role name (resource segment 1) from the assumed-role ARN, it checks membership; this error is thrown when the role name does not match any allowed node role.","triggerScenarios":"A caller assumed a valid role in the correct account (e.g. masters.cluster or bastion role) but the role name is not in NodesRoles — the ARN's role segment fails the whitelist loop in verifyCallerIdentity.","commonSituations":"A control-plane/master or bastion instance using the node bootstrap API; cluster renamed causing role name mismatch (nodes.newname vs nodes.oldname); custom instance profiles with differently named roles attached to worker instances; shared-AMI images retaining wrong role config.","solutions":["Verify the instance profile attached to the node is the cluster's nodes role (nodes.<clustername>) and not the masters or bastion role.","If intentional, add the role name to a.opt.NodesRoles / the kops cluster spec so it is accepted.","Check the cluster name used when creating the instance matches the API server's cluster config (role names embed the cluster name).","Replace any manually attached IAM role on the instance with the correct kOps-managed node instance profile."],"exampleFix":"// before: instance profile \"masters.cluster.example\" reaching the node bootstrap endpoint\n// after\naws iam attach-role-policy / instance profile = \"nodes.cluster.example\"  // or add to NodesRoles:\nNodesRoles: []string{\"nodes.cluster.example\"}","handlingStrategy":"validation","validationCode":"role := strings.Split(strings.Split(arn, \":\")[5], \"/\")[1]\nallowed := []string{\"nodes.\" + clusterName}\nif !slices.Contains(allowed, role) {\n    return fmt.Errorf(\"role %q is not a node role; attach the correct instance profile\", role)\n}","typeGuard":"func isNodeRoleARN(arn string, nodeRoles []string) bool {\n\tres := strings.Split(strings.Split(arn, \":\")[5], \"/\")\n\treturn len(res) >= 2 && slices.Contains(nodeRoles, res[1])\n}","tryCatchPattern":null,"preventionTips":["Check the instance profile attached to each node matches the cluster's nodes role.","Keep role names derived from the cluster name in sync when renaming clusters.","Only send bootstrap requests from worker nodes; masters/bastions use their own roles and endpoints."],"tags":["aws","iam","rbac","bootstrap","arn"],"backgroundTag":"unauthorized-iam-role","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}