kubernetes/kops · error
found multiple monitors with name: %s
Error message
found multiple monitors with name: %s
What it means
PoolMonitor.Find lists Octavia health monitors for the referenced pool and requires at most one match. When more than one monitor with the same name is found, kOps cannot determine which is the managed one and returns this error instead of guessing.
Source
Thrown at upup/pkg/fi/cloudup/openstacktasks/poolmonitor.go:68
return p.ID
}
func (p *PoolMonitor) Find(context *fi.CloudupContext) (*PoolMonitor, error) {
cloud := context.T.Cloud.(openstack.OpenstackCloud)
opt := monitors.ListOpts{
Name: fi.ValueOf(p.Name),
PoolID: fi.ValueOf(p.Pool.ID),
}
rs, err := cloud.ListMonitors(opt)
if err != nil {
return nil, err
}
if len(rs) == 0 {
return nil, nil
} else if len(rs) != 1 {
return nil, fmt.Errorf("found multiple monitors with name: %s", fi.ValueOf(p.Name))
}
found := rs[0]
actual := &PoolMonitor{
ID: new(found.ID),
Name: new(found.Name),
Pool: p.Pool,
Lifecycle: p.Lifecycle,
}
p.ID = actual.ID
return actual, nil
}
func (p *PoolMonitor) Run(context *fi.CloudupContext) error {
return fi.CloudupDefaultDeltaRunMethod(p, context)
}
func (_ *PoolMonitor) CheckChanges(a, e, changes *PoolMonitor) error {
if a == nil {View on GitHub (pinned to 4c8573c808)
Solutions
- List monitors (`openstack loadbalancer healthmonitor list`) and delete all but one with that name
- Keep one OpenStack project per cluster to avoid name collisions between clusters
- Re-run `kops update cluster` after cleanup so Find matches exactly one monitor
- Avoid manually creating monitors with names that kops manages
Example fix
// before: two monitors named 'api-monitor' on the pool openstack loadbalancer healthmonitor delete <duplicate-id> // after: single monitor remains and reconcile proceeds
Defensive patterns
Strategy: validation
Validate before calling
// detect duplicate monitors before reconcile
cmd := exec.Command("openstack", "loadbalancer", "healthmonitor", "list")
out, _ := cmd.Output()
if bytes.Count(out, []byte(monitorName)) > 1 {
return fmt.Errorf("duplicate monitor %s; remove extras", monitorName)
} Type guard
func uniqueMonitors(rs []monitors.Monitor) (*monitors.Monitor, error) {
if len(rs) == 0 { return nil, nil }
if len(rs) == 1 { return &rs[0], nil }
return nil, fmt.Errorf("found %d monitors with same name", len(rs))
} Try / catch
actual, err := task.Find(ctx)
if err != nil && strings.Contains(err.Error(), "found multiple monitors") {
// list monitors, delete duplicates, then retry reconcile
} Prevention
- Never hand-create health monitors with kops-managed names
- Use a dedicated project per cluster to prevent shared-name collisions
- Clean up leftovers from aborted updates before retrying
When it happens
Trigger: Listing monitors for the pool returns len(rs) != 1 with >1 result: duplicate health monitors were created on the pool by repeated manual creation or overlapping kops runs against the same project, all sharing the pool monitor's name.
Common situations: An earlier aborted update left a monitor behind and a retry created another; an operator manually added a monitor with the same name for testing; two clusters in one project producing identically named monitors on shared pools.
Related errors
- found multiple pools with name: %s
- failed to build load balancer client: %w
- cluster configured to use octavia, but router was not config
- error building lb client: %w
- loadbalancer API versions not found
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/d81f8a2808664c14.
Report an issue: GitHub.