kubernetes/kubernetes · error
adding Pod event handler: %w
Error message
adding Pod event handler: %w
What it means
Returned by NewController when `podInformer.Informer().AddEventHandler(...)` fails (job_controller.go:288-300). Same lifecycle semantics as the Job handler error: handlers must be registered before the informer runs. Failure aborts controller creation.
Source
Thrown at pkg/controller/job/job_controller.go:299
},
}); err != nil {
return nil, fmt.Errorf("adding Job event handler: %w", err)
}
jm.jobLister = jobInformer.Lister()
jm.jobStoreSynced = jobInformer.Informer().HasSynced
if _, err := podInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
jm.addPod(logger, obj)
},
UpdateFunc: func(oldObj, newObj interface{}) {
jm.updatePod(logger, oldObj, newObj)
},
DeleteFunc: func(obj interface{}) {
jm.deletePod(logger, obj, true)
},
}); err != nil {
return nil, fmt.Errorf("adding Pod event handler: %w", err)
}
jm.podStore = podInformer.Lister()
jm.podStoreSynced = podInformer.Informer().HasSynced
err := controller.AddPodControllerIndexer(podInformer.Informer())
if err != nil {
return nil, fmt.Errorf("adding Pod controller UID indexer: %w", err)
}
jm.podIndexer = podInformer.Informer().GetIndexer()
jm.updateStatusHandler = jm.updateJobStatus
jm.syncHandler = jm.syncJob
if feature.DefaultFeatureGate.Enabled(features.WorkloadWithJob) {
if err := jm.addSchedulingInformers(logger, workloadInformer, podGroupInformer); err != nil {
return nil, err
}
}View on GitHub (pinned to b882c60b40)
Solutions
- Register all handlers (Job + Pod + indexer) before `informerFactory.Start`.
- Ensure the core/v1 pod informer comes from the same factory passed to NewController.
- Inspect the wrapped error for a permissions/listwatch cause.
- Confirm kubeClient has list/watch on pods.
Example fix
// before: core factory started, then pod handler added coreInformerFactory.Start(ctx.Done()) jm, err := job.NewController(... coreInformerFactory.Core().V1().Pods() ...) // after jm, err := job.NewController(... coreInformerFactory.Core().V1().Pods() ...) coreInformerFactory.Start(ctx.Done())
Defensive patterns
Strategy: try-catch
Try / catch
// Same lifecycle guard as the Job handler: register Pod handler before factory.Start.
func buildThenStart(ctx context.Context, coreFactory informers.SharedInformerFactory, build func() error) error {
if err := build(); err != nil { return err } // adds Pod handler + indexer
coreFactory.Start(ctx.Done())
return nil
} Prevention
- Register Pod handler before the core informer factory starts.
- Source the pod informer from the same factory passed to NewController.
- Ensure kubeClient has list/watch on pods.
- Keep client-go and job controller versions aligned.
When it happens
Trigger: Pod informer already started; podInformer factory misconfigured; pod listwatch GVR (`""/v1/pods`) unavailable; reusing a stopped shared informer.
Common situations: Embedding the job controller and starting the core shared informer factory too early; apiserver temporarily refusing pod list/watch; client-go version skew.
Related errors
- adding Job event handler: %w
- adding Pod controller UID indexer: %w
- failed to create informer name: %w
- failed to create metadata client config: %w
- failed to create metadata client: %w
AI-assisted analysis of kubernetes/kubernetes@b882c60b40 (2026-08-07).
Data as JSON: /api/errors/a8c647edd1fb6bc5.
Report an issue: GitHub.