kubernetes/kops · error

failed to extract loadbalancer pages: %s

Error message

failed to extract loadbalancer pages: %s

What it means

This error is wrapped by the openstackCloud loadbalancer listing helper after `loadbalancers.ExtractLoadBalancers(allPages)` fails inside a RetryWithBackoff block. Listing succeeded at the HTTP level, but the returned pagination pages could not be decoded into []LoadBalancer structs. It almost always indicates an unexpected response body from the Octavia API rather than a caller mistake.

Source

Thrown at upup/pkg/fi/cloudup/openstack/loadbalancer.go:278

// ListLBs will list load balancers
func (c *openstackCloud) ListLBs(opt loadbalancers.ListOptsBuilder) (lbs []loadbalancers.LoadBalancer, err error) {
	return listLBs(c, opt)
}

func listLBs(c OpenstackCloud, opt loadbalancers.ListOptsBuilder) (lbs []loadbalancers.LoadBalancer, err error) {
	if c.LoadBalancerClient() == nil {
		// skip error because cluster delete will otherwise fail
		return lbs, nil
	}

	done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {
		allPages, err := loadbalancers.List(c.LoadBalancerClient(), opt).AllPages(context.TODO())
		if err != nil {
			return false, fmt.Errorf("failed to list loadbalancers: %s", err)
		}
		lbs, err = loadbalancers.ExtractLoadBalancers(allPages)
		if err != nil {
			return false, fmt.Errorf("failed to extract loadbalancer pages: %s", err)
		}
		return true, nil
	})
	if !done {
		if err == nil {
			err = wait.ErrWaitTimeout
		}
		return lbs, err
	}
	return lbs, nil
}

func (c *openstackCloud) GetLBStats(loadbalancerID string) (stats *loadbalancers.Stats, err error) {
	return getLBStats(c, loadbalancerID)
}

func getLBStats(c OpenstackCloud, loadbalancerID string) (stats *loadbalancers.Stats, err error) {
	if c.LoadBalancerClient() == nil {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped err (%s) to see the JSON unmarshal failure and confirm which field failed to decode.
  2. Verify the load-balancer service endpoint in the OpenStack catalog is Octavia (`openstack service list`) and matches the installed gophercloud SDK version.
  3. Retry with a newer kOps/gophercloud version that supports the Octavia API microversion deployed in your cloud.
  4. If the endpoint is Neutron LBaaS, migrate to Octavia or disable the loadbalancer feature in the cluster config.

Example fix

// before
allPages, err := loadbalancers.List(c.LoadBalancerClient(), opt).AllPages(context.TODO())
lbs, err = loadbalancers.ExtractLoadBalancers(allPages)
// after: log the underlying decode error to identify the schema mismatch
if err != nil {
	klog.V(2).Infof("extract loadbalancers failed: %v", err)
	return false, fmt.Errorf("failed to extract loadbalancer pages: %s", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if client == nil || endpointURL == nil {
	return fmt.Errorf("no load-balancer endpoint in catalog; cannot list loadbalancers")
}

Type guard

func hasLBClient(c kops_cloud.OpenstackCloud) bool {
	return c.LoadBalancerClient() != nil
}

Try / catch

done, err := tryListLBs(cloud)
if err != nil {
	if strings.Contains(err.Error(), "failed to extract loadbalancer pages") {
		klog.Warningf("Octavia response schema mismatch: %v — check SDK/cloud version", err)
		return nil, ErrOctaviaIncompatible
	}
	return nil, err
}

Prevention

When it happens

Trigger: Calling GetLoadbalancers (which runs loadbalancers.List(...).AllPages then ExtractLoadBalancers) when the Octavia/Neutron-LBaaS endpoint returns pages whose JSON schema does not match the gophercloud loadbalancers structs, e.g. a proxy or a different LBaaS version answering the request.

Common situations: Pointing kOps at an OpenStack deployment where the load-balancer endpoint is served by Neutron LBaaS v2 instead of Octavia; a misconfigured service catalog entry routing to a non-Octavia service; an intermediary returning an HTML error page with HTTP 200.

Related errors


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