{"record":{"id":"6bd90c459ac5894a","repo":"istio/istio","slug":"lock-must-not-be-nil","errorCode":null,"errorMessage":"lock must not be nil","messagePattern":"lock must not be nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pilot/pkg/leaderelection/k8sleaderelection/leaderelection.go","lineNumber":102,"sourceCode":"\t}\n\tif lec.LeaseDuration < 1 {\n\t\treturn nil, fmt.Errorf(\"leaseDuration must be greater than zero\")\n\t}\n\tif lec.RenewDeadline < 1 {\n\t\treturn nil, fmt.Errorf(\"renewDeadline must be greater than zero\")\n\t}\n\tif lec.RetryPeriod < 1 {\n\t\treturn nil, fmt.Errorf(\"retryPeriod must be greater than zero\")\n\t}\n\tif lec.Callbacks.OnStartedLeading == nil {\n\t\treturn nil, fmt.Errorf(\"callback OnStartedLeading must not be nil\")\n\t}\n\tif lec.Callbacks.OnStoppedLeading == nil {\n\t\treturn nil, fmt.Errorf(\"callback OnStoppedLeading  must not be nil\")\n\t}\n\n\tif lec.Lock == nil {\n\t\treturn nil, fmt.Errorf(\"lock must not be nil\")\n\t}\n\tle := LeaderElector{\n\t\tconfig:  lec,\n\t\tclock:   clock.RealClock{},\n\t\tmetrics: globalMetricsFactory.newLeaderMetrics(),\n\t}\n\tle.metrics.leaderOff(le.config.Name)\n\treturn &le, nil\n}\n\ntype KeyComparisonFunc func(existingKey string) bool\n\ntype LeaderElectionConfig struct {\n\t// Lock is the resource that will be used for locking\n\tLock k8sresourcelock.Interface\n\n\t// LeaseDuration is the duration that non-leader candidates will\n\t// wait to force acquire leadership. This is measured against time of","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/istio/istio/blob/8dc789c5cf17517c64e3c36cb3288230f149dfae/pilot/pkg/leaderelection/k8sleaderelection/leaderelection.go#L84-L120","documentation":"Validation error from NewLeaderElector in pilot/pkg/leaderelection/k8sleaderelection. The Lock field (a k8sresourcelock.Interface) is the resource the elector contends on (Lease, Endpoint, ConfigMap, or a MultiLock); a nil Lock means there is nothing to elect on, so the constructor rejects it. Locks are normally created via k8sresourcelock.New or NewFromKubeconfig.","triggerScenarios":"Omitting the Lock field when building LeaderElectionConfig, or a lock-construction call whose error was ignored so Lock stayed nil (Go returns a nil Interface on error). NewLeaderElector then fails this final check.","commonSituations":"Calling k8sresourcelock.NewFromKubeconfig and not handling its error (e.g. invalid lock-type) before assigning; wiring code that builds the lock conditionally and skips the assignment on some path; refactor that moved lock creation after elector creation.","solutions":["Create the lock first and handle its error: lock, err := k8sresourcelock.NewFromKubeconfig(...); if err != nil { return err }","Assign Lock: lec.Lock = lock before NewLeaderElector","Never ignore errors from lock constructors - they return nil on failure","Verify the kubeconfig/client used can access the target namespace and resource type"],"exampleFix":"// before\nlock, _ := k8sresourcelock.NewFromKubeconfig(t, ns, name, rlc, restCfg, renew) // error ignored; lock==nil\ncfg.Lock = lock // -> lock must not be nil\n\n// after\nlock, err := k8sresourcelock.NewFromKubeconfig(k8sresourcelock.LeasesResourceLock, ns, name, rlc, restCfg, renew)\nif err != nil {\n    return fmt.Errorf(\"creating leader election lock: %w\", err)\n}\ncfg.Lock = lock","handlingStrategy":"validation","validationCode":"if lec.Lock == nil {\n    return errors.New(\"leader election lock not constructed\")\n}\n// and check the constructor's error before assignment:\nlock, err := k8sresourcelock.NewFromKubeconfig(k8sresourcelock.LeasesResourceLock, ns, name, rlc, restCfg, renew)\nif err != nil {\n    return fmt.Errorf(\"lock construction: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"lock, err := k8sresourcelock.NewFromKubeconfig(...)\nif err != nil {\n    return err\n}\ncfg.Lock = lock // only assign on success","preventionTips":["Never discard errors from lock constructors; they return nil on failure","Create the lock immediately before the elector in the same function","Verify RBAC for the lock resource (leases/endpoints/configmaps) in the namespace"],"tags":["leader-election","configuration","validation"],"backgroundTag":null,"analyzedSha":"8dc789c5cf17517c64e3c36cb3288230f149dfae","analyzedAt":"2026-08-15T15:16:55.434Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}