kubernetes/kops · error

error creating LB pool: %v

Error message

error creating LB pool: %v

What it means

After the parent LB is ACTIVE, RenderOpenstack calls t.Cloud.CreatePool (POST /v2/lbaas/pools) and wraps any API failure. Common rejects are validation of protocol/LB method, quota limits, or the LB having moved out of ACTIVE state between the wait and the create.

Source

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

		// wait that lb is in ACTIVE state
		provisioningStatus, err := waitLoadbalancerActiveProvisioningStatus(t.Cloud.LoadBalancerClient(), fi.ValueOf(e.Loadbalancer.ID))
		if err != nil {
			return fmt.Errorf("failed to loadbalancer ACTIVE provisioning status %v: %v", provisioningStatus, err)
		}

		LbMethod := v2pools.LBMethodRoundRobin
		if fi.ValueOf(e.Loadbalancer.Provider) == "ovn" {
			LbMethod = v2pools.LBMethodSourceIpPort
		}
		poolopts := v2pools.CreateOpts{
			Name:           fi.ValueOf(e.Name),
			LBMethod:       LbMethod,
			Protocol:       v2pools.ProtocolTCP,
			LoadbalancerID: fi.ValueOf(e.Loadbalancer.ID),
		}
		pool, err := t.Cloud.CreatePool(poolopts)
		if err != nil {
			return fmt.Errorf("error creating LB pool: %v", err)
		}
		e.ID = new(pool.ID)

		return nil
	}

	klog.V(2).Infof("Openstack task LB::RenderOpenstack did nothing")
	return nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Read the wrapped error: 409 → re-run after LB is ACTIVE; 403/413 → raise pool quotas; 400 → fix CreateOpts/provider mismatch.
  2. For ovn provider, ensure LBMethod SOURCE_IP_PORT is used (kOps does this automatically — check the provider is correctly detected).
  3. Check/raise quotas: openstack quota show --load-balancer; remove unused pools.
  4. Re-run kops update once no other LB mutations are in flight to avoid ACTIVE-state races.

Example fix

// before: round-robin rejected by ovn
LBMethod: v2pools.LBMethodRoundRobin  // provider=ovn
// after
LbMethod := v2pools.LBMethodRoundRobin
if fi.ValueOf(e.Loadbalancer.Provider) == "ovn" {
	LbMethod = v2pools.LBMethodSourceIpPort
}
Defensive patterns

Strategy: validation

Validate before calling

if poolsUsed >= poolQuota { return fmt.Errorf("octavia pool quota exceeded for project") }
if provider == "ovn" && lbMethod != "SOURCE_IP_PORT" {
	return fmt.Errorf("provider ovn requires SOURCE_IP_PORT LB method")
}

Try / catch

if err := kopsUpdate(); err != nil {
	var apiErr gophercloud.ErrUnexpectedResponseCode
	if errors.As(err, &apiErr) {
		switch apiErr.StatusCode {
		case 409: return backoffAndRetry()          // LB left ACTIVE
		case 403, 413: return raiseQuotaAndRetry()  // quota
		case 400: return fixSpecAndRetry()          // validation
		}
	}
	return err
}

Prevention

When it happens

Trigger: CreatePool fails with 409 because LB is not ACTIVE (race), 403/413 quota exceeded (pools per LB/project), or invalid CreateOpts — e.g. unsupported LBMethod for the provider (SOURCE_IP_PORT only valid for ovn) or protocol mismatch.

Common situations: Projects at Octavia pool quota; concurrent operations flipping the LB back to PENDING_*; octavia-ovn provider rejecting ROUND_ROBIN; misconfigured provider string in the cluster spec.

Related errors


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