kubernetes/kops · error

NewLBListenerTaskFromCloud: failed to fetch pool %s: %v

Error message

NewLBListenerTaskFromCloud: failed to fetch pool %s: %v

What it means

After locating the pool and its member, PoolAssociation.Find calls NewLBPoolTaskFromCloud to reconstruct the pool task from cloud state. If that conversion fails, kOps wraps the failure (note the message misleadingly says 'NewLBListenerTaskFromCloud') and aborts Find, so the PoolAssociation's actual state cannot be computed.

Source

Thrown at upup/pkg/fi/cloudup/openstacktasks/poolassociation.go:105

	var found *v2pools.Member
	for _, member := range a.Members {
		poolMember, err := cloud.GetPoolMember(a.ID, member.ID)
		if err != nil {
			return nil, err
		}
		if fi.ValueOf(p.Name) == poolMember.Name {
			found = poolMember
			break
		}
	}
	// if not found it is created by returning nil, nil
	// this is needed for instance in initial installation
	if found == nil {
		return nil, nil
	}
	pool, err := NewLBPoolTaskFromCloud(cloud, p.Lifecycle, &a, nil)
	if err != nil {
		return nil, fmt.Errorf("NewLBListenerTaskFromCloud: failed to fetch pool %s: %v", fi.ValueOf(pool.Name), err)
	}

	actual := &PoolAssociation{
		ID:            new(found.ID),
		Name:          new(found.Name),
		Pool:          pool,
		ServerPrefix:  p.ServerPrefix,
		ClusterName:   p.ClusterName,
		InterfaceName: p.InterfaceName,
		ProtocolPort:  p.ProtocolPort,
		Lifecycle:     p.Lifecycle,
		Weight:        new(found.Weight),
	}
	p.ID = actual.ID
	return actual, nil
}

func (s *PoolAssociation) Run(context *fi.CloudupContext) error {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped %v error to see which sub-resource fetch failed (listener/loadbalancer lookup vs pool detail)
  2. Verify the pool's parent loadbalancer exists (`openstack loadbalancer show <lb-id>`); clean up orphaned pools if not
  3. Retry `kops update cluster` if Octavia returned a transient 5xx/429
  4. Confirm kops and the cluster's Octavia API versions are compatible (upgrade Octavia or kops)

Example fix

// before: orphaned pool whose loadbalancer was deleted manually
openstack loadbalancer pool delete <orphan-pool-id>
// after: let kops recreate loadbalancer + pool consistently
Defensive patterns

Strategy: fallback

Validate before calling

// verify the pool's parent loadbalancer exists before reconcile
out, err := exec.Command("openstack", "loadbalancer", "list").Output()
if err != nil { return err }
// if the pool exists but its LB is absent, delete the orphaned pool first

Type guard

func isNotFound(err error) bool {
	var gerr gophercloud.ErrUnexpectedResponseCode
	return errors.As(err, &gerr) && gerr.Actual == 404
}

Try / catch

pool, err := NewLBPoolTaskFromCloud(cloud, lifecycle, &a, nil)
if err != nil {
	if isNotFound(err) {
		// parent LB gone: treat association as absent and recreate
		return nil, nil
	}
	return nil, fmt.Errorf("failed to fetch pool: %v", err)
}

Prevention

When it happens

Trigger: NewLBPoolTaskFromCloud(cloud, p.Lifecycle, &a, nil) errors while rebuilding the pool task: the pool's parent loadbalancer/listener referenced by the cloud pool is missing or fetches fail, or Octavia returns an error reading pool detail (404 on a dangling pool, API failure).

Common situations: Loadbalancer was deleted out-of-band while its pool remains; Octavia API outage or throttling during reconcile; Octavia version mismatch where pool detail fields differ from what the kops task builder expects.

Related errors


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