cilium/cilium · error
invalid selector in CiliumNodeConfig %s: %w
Error message
invalid selector in CiliumNodeConfig %s: %w
What it means
Each listed CiliumNodeConfig's Spec.NodeSelector is converted to a label Selector via metav1.LabelSelectorAsSelector to test whether it matches this node's labels. Conversion of a valid stored CR is considered unreachable, but if it fails this error wraps the invalid selector, skipping all CNC matching.
Source
Thrown at pkg/option/resolver/resolver.go:310
return nil, nil, fmt.Errorf("could not get Node %s: %w", nodeName, err)
}
matching := map[string]ciliumv2.CiliumNodeConfig{}
// track names separately, since we will compute "priority" by lexicographic sort
var matchingNames []string
for _, override := range overrides {
// ignore empty overrides
if len(override.Spec.Defaults) == 0 {
continue
}
// if we're selecting on a list, then evaluate the node selector
if name == "" && override.Spec.NodeSelector != nil {
ls, err := metav1.LabelSelectorAsSelector(override.Spec.NodeSelector)
if err != nil { // unreachable
return nil, nil, fmt.Errorf("invalid selector in CiliumNodeConfig %s: %w", override.Name, err)
}
if ls.Matches(labels.Set(node.Labels)) {
matching[override.Name] = override
matchingNames = append(matchingNames, override.Name)
}
} else if name != "" {
matching[override.Name] = override
matchingNames = append(matchingNames, override.Name)
}
}
// Within overrides, lexicographical ordering determines priority.
slices.Sort(matchingNames)
out := make(map[string]string)
for _, name := range matchingNames {
for k, v := range matching[name].Spec.Defaults {
if errs := apivalidation.IsConfigMapKey(k); len(errs) > 0 {View on GitHub (pinned to ac7b90affa)
Solutions
- Fix the NodeSelector on the offending CiliumNodeConfig (the name is in the message): use valid keys, values, and operators (In, NotIn, Exists, DoesNotExist)
- Validate with kubectl: kubectl get ciliumnodeconfig <name> -o yaml and check spec.nodeSelector
- Re-create the CR via kubectl apply so API validation runs
- Upgrade cilium/client-go so LabelSelectorAsSelector handles the schema version in use
Example fix
// before
nodeSelector:
matchExpressions:
- key: kubernetes.io/os
operator: equals # invalid operator
values: [linux]
// after
nodeSelector:
matchExpressions:
- key: kubernetes.io/os
operator: In
values: [linux] Defensive patterns
Strategy: validation
Validate before calling
// Go: validate selectors of referenced CNCs before resolving
l, _ := client.CiliumV2().CiliumNodeConfigs(ns).List(ctx, metav1.ListOptions{})
for _, c := range l.Items {
if c.Spec.NodeSelector != nil {
if _, err := metav1.LabelSelectorAsSelector(c.Spec.NodeSelector); err != nil {
return fmt.Errorf("CNC %s has invalid nodeSelector: %w", c.Name, err)
}
}
} Try / catch
cfg, sources, err := resolver.ReadConfigSource(ctx, logger, client, nodeName, source)
if err != nil {
if strings.Contains(err.Error(), "invalid selector in CiliumNodeConfig") {
logger.Error("fix the NodeSelector on the named CiliumNodeConfig", "err", err)
}
return err
} Prevention
- Create CNCs only via kubectl apply so API selector validation runs
- Use only valid matchExpressions operators (In, NotIn, Exists, DoesNotExist)
- Lint CNC YAML against the cilium.io/v2 schema in CI
- Re-apply old CRs after cluster upgrades to re-run validation
When it happens
Trigger: LabelSelectorAsSelector returns an error, e.g. selector containing invalid keys/values that bypass API validation (hand-crafted CRs, direct etcd writes, or CRs created before validation was enforced).
Common situations: CiliumNodeConfig objects created via a client that skipped server-side selector validation, CRs copied from other resources with malformed matchExpressions (bad operator names), or cluster upgrade mixing schema versions.
Related errors
- failed to convert label selector: %w
- %q is not a valid label selector operator
- %q is not a valid selector operator
- invalid label selector: %w
- top-level description field found
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/b17694ca198e8f31.
Report an issue: GitHub.