kubernetes/kops · error

error extracting ports from pages: %v

Error message

error extracting ports from pages: %v

What it means

After successfully fetching all pages, listPorts (upup/pkg/fi/cloudup/openstack/port.go:115) calls ports.ExtractPorts to deserialize the paginated result into []ports.Port. If extraction fails — typically malformed or unexpected JSON in the response — this error is wrapped and returned after retries are exhausted.

Source

Thrown at upup/pkg/fi/cloudup/openstack/port.go:115

	}
}

func (c *openstackCloud) ListPorts(opt ports.ListOptsBuilder) ([]ports.Port, error) {
	return listPorts(c, opt)
}

func listPorts(c OpenstackCloud, opt ports.ListOptsBuilder) ([]ports.Port, error) {
	var p []ports.Port

	done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {
		allPages, err := ports.List(c.NetworkingClient(), opt).AllPages(context.TODO())
		if err != nil {
			return false, fmt.Errorf("error listing ports: %v", err)
		}

		r, err := ports.ExtractPorts(allPages)
		if err != nil {
			return false, fmt.Errorf("error extracting ports from pages: %v", err)
		}
		p = r
		return true, nil
	})
	if err != nil {
		return p, err
	} else if done {
		return p, nil
	} else {
		return p, wait.ErrWaitTimeout
	}
}

func (c *openstackCloud) DeletePort(portID string) error {
	return deletePort(c, portID)
}

func deletePort(c OpenstackCloud, portID string) error {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the raw response from the Neutron endpoint (curl with the token) to see what body is actually returned.
  2. Fix the endpoint URL in the OpenStack service catalog / OS_* env so the client talks to real Neutron, not a proxy or wrong service.
  3. Pin a compatible OpenStack client/microversion if the cloud's Neutron schema differs from the gophercloud expectations.
  4. Report/upgrade gophercloud if the cloud returns a valid but unsupported port schema.

Example fix

// before
r, err := ports.ExtractPorts(allPages)
if err != nil {
    return false, fmt.Errorf("error extracting ports from pages: %v", err)
}
// after — verify the endpoint returns real Neutron JSON before extraction
resp, _ := c.NetworkingClient().Get(ports.List(c.NetworkingClient(), opt).(ports.ListOpts).ToPortsListQuery().(string))
_ = resp
r, err := ports.ExtractPorts(allPages)
if err != nil {
    return false, fmt.Errorf("error extracting ports from pages (check Neutron endpoint/proxy): %v", err)
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Sanity-check that the endpoint speaks Neutron JSON before extracting pages
resp, err := http.Get(neutronEndpoint + "/ports?limit=1")
if err != nil {
    return fmt.Errorf("cannot reach Neutron: %w", err)
}
ct := resp.Header.Get("Content-Type")
if !strings.Contains(ct, "application/json") {
    return fmt.Errorf("endpoint returned %q, not JSON — wrong endpoint or intercepting proxy", ct)
}

Try / catch

ports, err := listPorts(c, opts)
if err != nil {
    if strings.Contains(err.Error(), "error extracting ports from pages") {
        // response shape unexpected: verify endpoint URL, proxies, and Neutron version
        return fmt.Errorf("non-JSON or unsupported Neutron response: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: ports.ExtractPorts(allPages) errors because the response body is not a valid Neutron port list — an API proxy returned an HTML error page, a nonstandard Neutron fork/version emits a different schema, or the page collection is corrupt.

Common situations: Corporate proxy or middlebox rewriting JSON responses; very old/new Neutron microversion with schema drift; a service (like a login portal) answering on the Neutron endpoint due to misconfigured endpoint URL in the catalog.

Related errors


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