k3s-io/k3s · error
all cloud-provider functionality disabled by config
Error message
all cloud-provider functionality disabled by config
What it means
The k3s cloud provider registers under the name 'k3s' with lbEnabled and nodeEnabled defaulting to true. If the JSON cloud-config supplied to the controller-manager sets both to false, the provider has nothing to run and registration returns an error instead of a silent no-op provider.
Source
Thrown at pkg/cloudprovider/cloudprovider.go:78
Config: Config{
LBDefaultPriorityClassName: DefaultLBPriorityClassName,
LBEnabled: true,
LBImage: DefaultLBImage,
LBNamespace: DefaultLBNS,
NodeEnabled: true,
},
}
if config != nil {
var bytes []byte
bytes, err = io.ReadAll(config)
if err == nil {
err = json.Unmarshal(bytes, &k.Config)
}
}
if !k.LBEnabled && !k.NodeEnabled {
return nil, errors.New("all cloud-provider functionality disabled by config")
}
return &k, err
})
}
func (k *k3s) Initialize(clientBuilder cloudprovider.ControllerClientBuilder, stop <-chan struct{}) {
ctx := logger.NewContext(wait.ContextForChannel(stop), controllerName)
config := clientBuilder.ConfigOrDie(controllerName)
k.client = kubernetes.NewForConfigOrDie(config)
if k.LBEnabled {
// Wrangler controller and caches are only needed if the load balancer controller is enabled.
k.recorder = util.BuildControllerEventRecorder(ctx, k.client, controllerName, meta.NamespaceAll)
coreFactory := core.NewFactoryFromConfigOrDie(config)
k.nodeCache = coreFactory.Core().V1().Node().Cache()
lbCoreFactory := core.NewFactoryFromConfigWithOptionsOrDie(config, &generic.FactoryOptions{Namespace: k.LBNamespace})View on GitHub (pinned to 6ba341e396)
Solutions
- If neither function is wanted, do not load the k3s cloud provider at all — drop --cloud-provider=k3s / the cloud-config file
- Keep at least one of lbEnabled/nodeEnabled true in the JSON config
- To disable only ServiceLB, use the k3s flag --disable-service-lb rather than blanking cloud-config
Example fix
# before (cloud-config.json)
{"lbEnabled":false,"nodeEnabled":false}
# after (ServiceLB off, node controller still active)
{"lbEnabled":false,"nodeEnabled":true} Defensive patterns
Strategy: validation
Validate before calling
// validate cloud-config before handing it to the controller-manager
type k3sCCMConfig struct {
LBEnabled *bool `json:"lbEnabled"`
NodeEnabled *bool `json:"nodeEnabled"`
}
var c k3sCCMConfig
if err := json.Unmarshal(raw, &c); err == nil {
lb := c.LBEnabled == nil || *c.LBEnabled
node := c.NodeEnabled == nil || *c.NodeEnabled
if !lb && !node {
return errors.New("cloud-config disables all k3s provider functionality; omit --cloud-provider=k3s instead")
}
} Type guard
func k3sProviderConfigUsable(cfg []byte) bool {
var c struct {
LBEnabled *bool `json:"lbEnabled"`
NodeEnabled *bool `json:"nodeEnabled"`
}
if json.Unmarshal(cfg, &c) != nil {
return true // parse error handled elsewhere
}
lb := c.LBEnabled == nil || *c.LBEnabled
node := c.NodeEnabled == nil || *c.NodeEnabled
return lb || node
} Prevention
- Don't load the k3s cloud provider when both controllers are unwanted
- Prefer k3s CLI flags (--disable-service-lb) over cloud-config toggles for disabling features
- Schema-validate cloud-config JSON in CI
When it happens
Trigger: Starting kube-controller-manager / k3s's embedded cloud controller with `--cloud-provider=k3s --cloud-config=<file>` where the file is `{"lbEnabled":false,"nodeEnabled":false}`.
Common situations: Operators trying to switch off ServiceLB and the node controller via cloud-config while still loading the k3s provider; config files copied from docs with both toggles flipped; leftover cloud-config when migrating to a different CCM.
Related errors
- etcd-s3-timeout must be greater than 0s
- toleration with empty key must have operator 'Exists'
- toleration with operator 'Exists' must have an empty value
- critical configuration value mismatch between servers
- s3 bucket name was not set
AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15).
Data as JSON: /api/errors/bc012d7c183fb0e5.
Report an issue: GitHub.