{"record":{"id":"a896673472af408f","repo":"kubernetes/kops","slug":"role-v-does-not-have-serviceaccount","errorCode":null,"errorMessage":"role %v does not have ServiceAccount","messagePattern":"role (.+?) does not have ServiceAccount","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/iam/types.go","lineNumber":54,"sourceCode":"\t}\n\treturn statements, nil\n}\n\ntype IAMModelContext struct {\n\t// AWSAccountID holds the 12 digit AWS account ID, when running on AWS\n\tAWSAccountID string\n\t// AWSPartition defines the partition of the AWS account, typically \"aws\", \"aws-cn\", or \"aws-us-gov\"\n\tAWSPartition string\n\n\t// Cluster holds the cluster we are working with.\n\tCluster *kops.Cluster\n}\n\n// IAMNameForServiceAccountRole determines the name of the IAM Role and Instance Profile to use for the service-account role\nfunc (b *IAMModelContext) IAMNameForServiceAccountRole(role Subject) (string, error) {\n\tserviceAccount, ok := role.ServiceAccount()\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"role %v does not have ServiceAccount\", role)\n\t}\n\tname := IAMNameForServiceAccountRole(serviceAccount.Name, serviceAccount.Namespace, b.ClusterName())\n\treturn name, nil\n}\n\n// ClusterName returns the cluster name\nfunc (b *IAMModelContext) ClusterName() string {\n\treturn b.Cluster.ObjectMeta.Name\n}\n\nfunc IAMNameForServiceAccountRole(name, namespace, clusterName string) string {\n\trole := name + \".\" + strings.ReplaceAll(namespace, \"*\", \"wildcard\") + \".sa.\" + clusterName\n\trole = truncate.TruncateString(role, truncate.TruncateStringOptions{MaxLength: MaxLengthIAMRoleName, AlwaysAddHash: false})\n\treturn role\n}\n","sourceCodeStart":36,"sourceCodeEnd":70,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/iam/types.go#L36-L70","documentation":"Returned by IAMNameForServiceAccountRole when the Subject it is given has an empty ServiceAccount field. kOps derives IAM role/instance-profile names only for Kubernetes service accounts, so a subject without one (e.g. a user or group) cannot be mapped to a role name and the model build aborts.","triggerScenarios":"Thrown at pkg/model/iam/types.go:54 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Ensure every Subject used for service-account IAM mapping includes a fully qualified serviceAccount name such as system:serviceaccount:<namespace>:<name>","Remove non-service-account subjects from the IAM/serviceAccount role mappings in the cluster spec","Edit the cluster with `kops edit cluster` and re-run `kops update cluster` to validate"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}