kubernetes/kops · error

Multiple pools found for name %s

Error message

Multiple pools found for name %s

What it means

LBPool.Find expects the name/ID filter to resolve to at most one pool; if ListPools returns more than one match it refuses to guess and returns this error. It protects reconciliation from mutating the wrong pool.

Source

Thrown at upup/pkg/fi/cloudup/openstacktasks/lbpool.go:100

func (p *LBPool) Find(context *fi.CloudupContext) (*LBPool, error) {
	if p.Name == nil && p.ID == nil {
		return nil, nil
	}

	cloud := context.T.Cloud.(openstack.OpenstackCloud)
	poolList, err := cloud.ListPools(v2pools.ListOpts{
		ID:   fi.ValueOf(p.ID),
		Name: fi.ValueOf(p.Name),
	})
	if err != nil {
		return nil, fmt.Errorf("Failed to list pools: %v", err)
	}
	if len(poolList) == 0 {
		return nil, nil
	}
	if len(poolList) > 1 {
		return nil, fmt.Errorf("Multiple pools found for name %s", fi.ValueOf(p.Name))
	}

	return NewLBPoolTaskFromCloud(cloud, p.Lifecycle, &poolList[0], p)
}

func (s *LBPool) Run(context *fi.CloudupContext) error {
	return fi.CloudupDefaultDeltaRunMethod(s, context)
}

func (_ *LBPool) CheckChanges(a, e, changes *LBPool) error {
	if a == nil {
		if e.Name == nil {
			return fi.RequiredField("Name")
		}
	} else {
		if changes.ID != nil {
			return fi.CannotChangeField("ID")
		}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. List and inspect duplicates: openstack loadbalancer pool list | grep <name>, then delete the stale/orphan pool.
  2. Disambiguate by fixing kops state to carry the pool ID so the filter matches exactly one.
  3. Rename pools you own outside kops to avoid collisions with the kops-managed name.
  4. Ensure unique cluster names per OpenStack project to prevent leftovers colliding.

Example fix

// before: two pools named api-pool
$ openstack loadbalancer pool delete <stale-pool-id> --wait
// after
$ kops update cluster --name mycluster --yes  # now resolves to a single pool
Defensive patterns

Strategy: validation

Validate before calling

pools := octaviaPoolList(name)
if len(pools) > 1 {
	ids := poolIDs(pools)
	return fmt.Errorf("project has %d pools named %q (%v); delete or rename duplicates before kops update", len(pools), name, ids)
}

Try / catch

if err := kopsUpdate(); err != nil {
	if strings.Contains(err.Error(), "Multiple pools found for name") {
		return dedupePoolsByName(extractName(err)) // interactive cleanup then retry
	}
	return err
}

Prevention

When it happens

Trigger: Two or more Octavia pools share the name recorded in kops state (pool names are not enforced unique project-wide), and Find is called with only Name set (p.ID nil).

Common situations: Leftover pools from an aborted/previous cluster with the same cluster name; duplicate pools created manually or by another tool; reusing a cluster name after incomplete cleanup.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/f7faf81bcdfac55e. Report an issue: GitHub.