kubernetes/kubernetes · critical

error creating ServiceAccount controller: %w

Error message

error creating ServiceAccount controller: %w

What it means

Returned by newServiceAccountController when serviceaccountcontroller.NewServiceAccountsController fails (core.go:584-592). The constructor validates its ServiceAccount/Namespace informers and client options; nil informers or a nil client are the usual cause. The %w is the constructor error.

Source

Thrown at cmd/kube-controller-manager/app/core.go:592

	}
}

func newServiceAccountController(ctx context.Context, controllerContext ControllerContext, controllerName string) (Controller, error) {
	client, err := controllerContext.NewClient("service-account-controller")
	if err != nil {
		return nil, err
	}
	logger := klog.FromContext(ctx)

	sac, err := serviceaccountcontroller.NewServiceAccountsController(
		logger,
		controllerContext.InformerFactory.Core().V1().ServiceAccounts(),
		controllerContext.InformerFactory.Core().V1().Namespaces(),
		client,
		serviceaccountcontroller.DefaultServiceAccountsControllerOptions(),
	)
	if err != nil {
		return nil, fmt.Errorf("error creating ServiceAccount controller: %w", err)
	}

	return newControllerLoop(func(ctx context.Context) {
		sac.Run(ctx, 1)
	}, controllerName), nil
}

func newTTLControllerDescriptor() *ControllerDescriptor {
	return &ControllerDescriptor{
		name:        names.TTLController,
		aliases:     []string{"ttl"},
		constructor: newTTLController,
	}
}

func newTTLController(ctx context.Context, controllerContext ControllerContext, controllerName string) (Controller, error) {
	client, err := controllerContext.NewClient("ttl-controller")
	if err != nil {

View on GitHub (pinned to b882c60b40)

Solutions

  1. Inspect %w for the named nil/invalid argument
  2. Ensure Core().V1().ServiceAccounts() and Namespaces() informers are initialized
  3. Rebuild from unmodified sources
  4. If SA token automation is unwanted, disable via --controllers=-serviceaccount

Example fix

// before: custom build passing nil SA informer
// after:
//   serviceaccountcontroller.NewServiceAccountsController(logger,
//     informerFactory.Core().V1().ServiceAccounts(),
//     informerFactory.Core().V1().Namespaces(), client, opts)
Defensive patterns

Strategy: type-guard

Validate before calling

if client == nil || saInformer == nil || nsInformer == nil {
    return errors.New("nil client or informer for SA controller")
}

Type guard

func hasSynced(i cache.SharedIndexInformer) bool { return i != nil && i.HasSynced() }

Try / catch

null

Prevention

When it happens

Trigger: KCM startup reaching the SA controller with a nil ServiceAccount or Namespace informer, or with DefaultServiceAccountsControllerOptions containing an invalid value. Stock builds always wire these informers.

Common situations: Custom KCM build missing informer init; disabling the namespace informer while the SA controller is enabled; providing incompatible options via a patched DefaultServiceAccountsControllerOptions.

Related errors


AI-assisted analysis of kubernetes/kubernetes@b882c60b40 (2026-08-07). Data as JSON: /api/errors/f6728d6d8ac37b08. Report an issue: GitHub.