kubernetes/kops · error

error updating LB listener: %v

Error message

error updating LB listener: %v

What it means

Raised when the LBListener task detects changed AllowedCIDRs and calls Octavia's listeners.Update to refresh the VIP ACL allow-list. Any API error from PATCH /v2/lbaas/listeners/{id} is wrapped here. It only fires when VIP ACL support is enabled (UseLoadBalancerVIPACL) and the provider is not ovn; otherwise the update is silently skipped.

Source

Thrown at upup/pkg/fi/cloudup/openstacktasks/lblistener.go:178

		if useVIPACL && (fi.ValueOf(e.Pool.Loadbalancer.Provider) != "ovn") {
			listeneropts.AllowedCIDRs = e.AllowedCIDRs
		}

		listener, err := t.Cloud.CreateListener(listeneropts)
		if err != nil {
			return fmt.Errorf("error creating LB listener: %v", err)
		}
		e.ID = new(listener.ID)
		return nil
	} else if len(changes.AllowedCIDRs) > 0 {
		if useVIPACL && (fi.ValueOf(a.Pool.Loadbalancer.Provider) != "ovn") {
			opts := listeners.UpdateOpts{
				AllowedCIDRs: &changes.AllowedCIDRs,
			}
			_, err := listeners.Update(context.TODO(), t.Cloud.LoadBalancerClient(), fi.ValueOf(a.ID), opts).Extract()
			if err != nil {
				return fmt.Errorf("error updating LB listener: %v", err)
			}
		} else {
			klog.V(2).Infof("Openstack Octavia VIPACLs not supported")
		}
		return nil
	}
	klog.V(2).Infof("Openstack task LB::RenderOpenstack did nothing")
	return nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped error; if 404, delete/recreate the load balancer task so a fresh listener ID is used (kops replace/delete the LB resources).
  2. Validate each admin-access CIDR is a valid non-overlapping CIDR before updating.
  3. Wait for the listener/load balancer to leave PENDING_* state, then re-run the update.
  4. Confirm the Octavia deployment supports allowed_cidrs and that the provider is not ovn (ovn ignores VIP ACLs by design).

Example fix

// before: updating a deleted listener
_, err := listeners.Update(ctx, client, fi.ValueOf(a.ID), opts).Extract()
// after: re-listen if the ID is stale
listenerList, _ := listeners.List(client, listeners.ListOpts{Name: fi.ValueOf(a.Name)}).AllPages(ctx)
items, _ := listeners.ExtractListeners(listenerList)
if len(items) > 0 && items[0].ID != fi.ValueOf(a.ID) {
	return fmt.Errorf("listener %s not found; re-run cluster update to recreate", fi.ValueOf(a.ID))
}
_, err := listeners.Update(ctx, client, items[0].ID, opts).Extract()
Defensive patterns

Strategy: validation

Validate before calling

for _, cidr := range newAllowedCIDRs {
	if _, _, err := net.ParseCIDR(cidr); err != nil { return fmt.Errorf("invalid admin-access CIDR %q: %w", cidr, err) }
}
listener := octaviaListenerGet(listenerID)
if listener == nil { return fmt.Errorf("listener %s missing; recreate LB before updating ACL", listenerID) }
if listener.ProvisioningStatus != "ACTIVE" { return fmt.Errorf("listener %s not ACTIVE", listenerID) }

Try / catch

if err := updateAdminAccess(cidrs); err != nil {
	var notFound gophercloud.ErrDefault404
	if errors.As(err, &notFound) {
		// stale listener ID: recreate resources via kops replace
		return recreateLoadBalancer()
	}
	return err
}

Prevention

When it happens

Trigger: kops update where cluster spec AllowedCIDRs changed (or --admin-access changed) and listeners.Update on the existing listener fails: invalid CIDR list, listener in immutable/PENDING state, 404 for stale listener ID, or auth failure.

Common situations: Operator runs `kops update cluster --admin-access=...`; the listener ID in state no longer exists because the LB was deleted out-of-band; Octavia version too old to support allowed_cidrs; provider is ovn but VIP ACL flag wrongly enabled (error would come from the API reject).

Related errors


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