{"record":{"id":"780dc283ca112d19","repo":"kubernetes/kops","slug":"node-identity-is-required","errorCode":null,"errorMessage":"node identity is required","messagePattern":"node identity is required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/kops-controller/pkg/server/node_config.go","lineNumber":38,"sourceCode":"\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"k8s.io/apimachinery/pkg/util/validation/field\"\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/kops/pkg/apis/kops\"\n\tkopsvalidation \"k8s.io/kops/pkg/apis/kops/validation\"\n\t\"k8s.io/kops/pkg/apis/nodeup\"\n\t\"k8s.io/kops/pkg/bootstrap\"\n\t\"k8s.io/kops/pkg/commands\"\n\t\"k8s.io/kops/pkg/nodeidentity/clusterapi\"\n)\n\nfunc (s *Server) getNodeConfig(ctx context.Context, req *nodeup.BootstrapRequest, identity *bootstrap.VerifyResult) (*nodeup.NodeConfig, error) {\n\tlog := klog.FromContext(ctx)\n\n\tif identity == nil {\n\t\treturn nil, fmt.Errorf(\"node identity is required\")\n\t}\n\n\tlog.Info(\"getting node config\", \"req\", req, \"identity\", identity)\n\n\tinstanceGroupName := identity.InstanceGroupName\n\tif instanceGroupName == \"\" {\n\t\tif identity.CAPIMachine == nil {\n\t\t\treturn nil, fmt.Errorf(\"did not find owner for node %q\", identity.NodeName)\n\t\t}\n\t\t// CAPI path: the InstanceGroup is synthesized from the Machine and\n\t\t// the name never reaches the configBase path, so we don't validate it.\n\t} else if errs := kopsvalidation.ValidateInstanceGroupName(instanceGroupName, field.NewPath(\"instanceGroupName\")); len(errs) > 0 {\n\t\treturn nil, fmt.Errorf(\"invalid InstanceGroup name: %v\", errs.ToAggregate())\n\t}\n\n\tvar nodeConfig *nodeup.NodeConfig\n\n\tconfigBuilder := &commands.ConfigBuilder{","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops-controller/pkg/server/node_config.go#L20-L56","documentation":"In kops-controller's bootstrap server, getNodeConfig refuses to serve a node configuration when the identity argument is nil. bootstraptNodeAuthorization verifies the request's identity first; if that verification step failed silently or was skipped, the code defensively rejects the request rather than serving cluster secrets to an unauthenticated caller. This is a server-side guard, so it usually indicates an internal logic/state problem in the verification chain rather than bad user input.","triggerScenarios":"A request reaches getNodeConfig with identity == nil — i.e. bootstrap passed nil for the *bootstrap.VerifyResult. This happens when the calling code path does not run (or ignores the result of) the identity verification step before calling getNodeConfig.","commonSituations":"Custom or patched builds of kops-controller where the verify step was made optional; a code change that calls getNodeConfig directly without a VerifyResult; misconfigured bootstrap authentication so verification is skipped and a nil result is propagated downstream.","solutions":["Ensure bootstrap always runs the identity verification and returns a non-nil *bootstrap.VerifyResult before calling getNodeConfig","If you patched kops-controller, restore the code path that computes identity and returns early on verification failure instead of passing nil","Check the controller logs for the earlier verification failure that led to a nil identity","Upgrade to a released kops-controller version if running a modified binary"],"exampleFix":"// before (skips verification)\nnodeConfig, err := s.getNodeConfig(ctx, req, nil)\n// after\nidentity, err := s.verifyNode(ctx, req)\nif err != nil {\n\treturn nil, fmt.Errorf(\"verifying node: %w\", err)\n}\nnodeConfig, err := s.getNodeConfig(ctx, req, identity)","handlingStrategy":"type-guard","validationCode":"if identity == nil {\n\treturn fmt.Errorf(\"node identity is required\")\n}","typeGuard":"func hasIdentity(v *bootstrap.VerifyResult) bool { return v != nil }","tryCatchPattern":"if err != nil {\n\tif strings.Contains(err.Error(), \"node identity is required\") {\n\t\t// re-run node bootstrap verification before retrying\n\t\treturn reverifyAndBootstrap(node)\n\t}\n\treturn err\n}","preventionTips":["Always run the identity verification step before requesting a node config","Never pass nil VerifyResult through call chains; return early on verification failure","Add unit tests asserting getNodeConfig is never called with nil identity"],"tags":["kubernetes","kops","bootstrap","authentication"],"backgroundTag":"missing-identity-verification","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"}