cilium/cilium · error
%w: %s on pools %s and %s
Error message
%w: %s on pools %s and %s
What it means
validateFilters rejects pool configs where the same interface name (IfName) appears in more than one CiliumNetworkDriverDevicePoolConfig. It wraps errIfNameInMultiplePools and names the offending interface and both conflicting pools. An interface can only belong to a single pool.
Source
Thrown at pkg/networkdriver/config.go:21
package networkdriver
import (
"errors"
"fmt"
"slices"
"github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2alpha1"
)
// validateFilters ensures that we do not have more than one filter matching the same device.
// some filter fields can be shared among devices (ex: driver, vendor, device id, pf name), but others
// can't (ex: ifname, pciaddr).
func validateFilters(this v2alpha1.CiliumNetworkDriverDevicePoolConfig, others ...v2alpha1.CiliumNetworkDriverDevicePoolConfig) error {
for _, ifname := range this.Filter.IfNames {
for _, otherPool := range others {
if slices.Contains(otherPool.Filter.IfNames, ifname) {
return fmt.Errorf("%w: %s on pools %s and %s", errIfNameInMultiplePools, ifname, this.PoolName, otherPool.PoolName)
}
}
}
return nil
}
// validatePools ensures that there are not any conflicting pool definitions.
func validatePools(this v2alpha1.CiliumNetworkDriverDevicePoolConfig, others ...v2alpha1.CiliumNetworkDriverDevicePoolConfig) error {
for _, p := range others {
if this.PoolName == p.PoolName {
return fmt.Errorf("%w: %s", errDuplicatedPoolName, this.PoolName)
}
if err := validateFilters(this, others...); err != nil {
return err
}
}View on GitHub (pinned to ac7b90affa)
Solutions
- Remove the duplicated ifName from one of the pools' filter.ifNames lists
- Give each pool a disjoint set of interface names so filters don't overlap
- Use shared fields (driver, vendor, deviceId, pfName) for grouping, but keep exclusive fields like ifName/pciAddr unique per pool
Example fix
// before
pools:
- name: pool-a
filter: {ifNames: [eth1, eth2]}
- name: pool-b
filter: {ifNames: [eth1, eth3]}
// after
pools:
- name: pool-a
filter: {ifNames: [eth1, eth2]}
- name: pool-b
filter: {ifNames: [eth3, eth4]} Defensive patterns
Strategy: validation
Validate before calling
func ifNamesDisjoint(pools []v2alpha1.CiliumNetworkDriverDevicePoolConfig) error {
seen := map[string]string{}
for _, p := range pools {
for _, n := range p.Filter.IfNames {
if owner, ok := seen[n]; ok {
return fmt.Errorf("ifname %s in pools %s and %s", n, owner, p.PoolName)
}
seen[n] = p.PoolName
}
}
return nil
} Try / catch
if err := validateConfig(cfg); err != nil {
if errors.Is(err, errIfNameInMultiplePools) {
// surface which pools conflict; abort apply
}
return err
} Prevention
- Validate pool configs in CI before applying
- Keep ifName/pciAddr filters exclusive per pool
- Review copy-pasted pool blocks for overlapping filters
When it happens
Trigger: Two device pools in the CiliumNetworkDriver config list the same entry in spec.pools[].filter.ifNames; validateFilters is invoked from validatePools while checking one pool against all others.
Common situations: Copy-pasting a pool definition and forgetting to change the ifNames filter; merging two configs where both claim e.g. eth1; typo'd ifname that coincidentally matches another pool's entry.
Related errors
- %w: %s
- max port value, %d, is less than or equal to min port value,
- cluster is unset
- namespace is unset
- name is unset
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/e2ef1a883a54e82f.
Report an issue: GitHub.