{"record":{"id":"cb0e9f80a7df2388","repo":"kubernetes/kubernetes","slug":"nil-endpointslice-passed-to-servicecontrollerkey","errorCode":null,"errorMessage":"nil EndpointSlice passed to serviceControllerKey()","messagePattern":"nil EndpointSlice passed to serviceControllerKey\\(\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/controller/endpointslicemirroring/utils.go","lineNumber":218,"sourceCode":"\t// state is unrecorded.\n\ttombstone, ok := obj.(cache.DeletedFinalStateUnknown)\n\tif !ok {\n\t\tutilruntime.HandleError(fmt.Errorf(\"couldn't get object from tombstone %#v\", obj))\n\t\treturn nil\n\t}\n\tendpointSlice, ok := tombstone.Obj.(*discovery.EndpointSlice)\n\tif !ok {\n\t\tutilruntime.HandleError(fmt.Errorf(\"tombstone contained object that is not an EndpointSlice resource: %#v\", obj))\n\t\treturn nil\n\t}\n\treturn endpointSlice\n}\n\n// endpointsControllerKey returns a controller key for an Endpoints resource but\n// derived from an EndpointSlice.\nfunc endpointsControllerKey(endpointSlice *discovery.EndpointSlice) (string, error) {\n\tif endpointSlice == nil {\n\t\treturn \"\", fmt.Errorf(\"nil EndpointSlice passed to serviceControllerKey()\")\n\t}\n\tserviceName, ok := endpointSlice.Labels[discovery.LabelServiceName]\n\tif !ok || serviceName == \"\" {\n\t\treturn \"\", fmt.Errorf(\"EndpointSlice missing %s label\", discovery.LabelServiceName)\n\t}\n\treturn fmt.Sprintf(\"%s/%s\", endpointSlice.Namespace, serviceName), nil\n}\n\n// skipMirror return true if the LabelSkipMirror label has been set to\n// \"true\".\nfunc skipMirror(labels map[string]string) bool {\n\tskipMirror, _ := labels[discovery.LabelSkipMirror]\n\treturn skipMirror == \"true\"\n}\n\n// hasLeaderElection returns true if the LeaderElectionRecordAnnotationKey is\n// set as an annotation.\nfunc hasLeaderElection(annotations map[string]string) bool {","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/kubernetes/kubernetes/blob/94c136764292cc5fac976c0de6587daaea56410f/pkg/controller/endpointslicemirroring/utils.go#L200-L236","documentation":"Emitted by endpointsControllerKey when called with a nil EndpointSlice pointer. The function derives a namespace/name key from the EndpointSlice to queue the corresponding Endpoints resource for reconciliation. A nil slice has no namespace or labels, so the key cannot be derived.","triggerScenarios":"queueEndpointsForEndpointSlice is called with a nil *discovery.EndpointSlice. This should not happen in normal flow since callers check for nil before calling, but could occur if a code path or test invokes endpointsControllerKey directly with nil.","commonSituations":"Direct unit tests of endpointsControllerKey passing nil. A logic bug where a nil check is skipped before calling the function. Extremely unlikely in production given the controller's nil guards upstream.","solutions":["Ensure callers check endpointSlice != nil before calling endpointsControllerKey.","In tests, always pass a valid *discovery.EndpointSlice.","If seen in production, trace the call stack to find which code path skipped the nil guard.","The controller already handles this gracefully by logging and returning."],"exampleFix":"// before\nkey, err := endpointsControllerKey(nil)\n\n// after\nif endpointSlice == nil {\n    return\n}\nkey, err := endpointsControllerKey(endpointSlice)","handlingStrategy":"validation","validationCode":"if endpointSlice == nil {\n    // skip calling endpointsControllerKey\n    return\n}","typeGuard":"func isNonNilEndpointSlice(slice *discovery.EndpointSlice) bool {\n    return slice != nil\n}","tryCatchPattern":null,"preventionTips":["Always nil-check before calling endpointsControllerKey.","In tests, pass valid *discovery.EndpointSlice instances.","Ensure upstream callers (queueEndpointsForEndpointSlice) retain their nil guards."],"tags":["endpointslice-mirroring","nil-check","endpointslice","kubernetes-controller"],"backgroundTag":null,"analyzedSha":"94c136764292cc5fac976c0de6587daaea56410f","analyzedAt":"2026-08-08T23:58:27.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}