{"record":{"id":"96207ff0e603113b","repo":"kubernetes/kops","slug":"error-extracting-ports-from-pages-v","errorCode":null,"errorMessage":"error extracting ports from pages: %v","messagePattern":"error extracting ports from pages: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/openstack/port.go","lineNumber":115,"sourceCode":"\t}\n}\n\nfunc (c *openstackCloud) ListPorts(opt ports.ListOptsBuilder) ([]ports.Port, error) {\n\treturn listPorts(c, opt)\n}\n\nfunc listPorts(c OpenstackCloud, opt ports.ListOptsBuilder) ([]ports.Port, error) {\n\tvar p []ports.Port\n\n\tdone, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {\n\t\tallPages, err := ports.List(c.NetworkingClient(), opt).AllPages(context.TODO())\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"error listing ports: %v\", err)\n\t\t}\n\n\t\tr, err := ports.ExtractPorts(allPages)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"error extracting ports from pages: %v\", err)\n\t\t}\n\t\tp = r\n\t\treturn true, nil\n\t})\n\tif err != nil {\n\t\treturn p, err\n\t} else if done {\n\t\treturn p, nil\n\t} else {\n\t\treturn p, wait.ErrWaitTimeout\n\t}\n}\n\nfunc (c *openstackCloud) DeletePort(portID string) error {\n\treturn deletePort(c, portID)\n}\n\nfunc deletePort(c OpenstackCloud, portID string) error {","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/openstack/port.go#L97-L133","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the raw response from the Neutron endpoint (curl with the token) to see what body is actually returned.","Fix the endpoint URL in the OpenStack service catalog / OS_* env so the client talks to real Neutron, not a proxy or wrong service.","Pin a compatible OpenStack client/microversion if the cloud's Neutron schema differs from the gophercloud expectations.","Report/upgrade gophercloud if the cloud returns a valid but unsupported port schema."],"exampleFix":"// before\nr, err := ports.ExtractPorts(allPages)\nif err != nil {\n    return false, fmt.Errorf(\"error extracting ports from pages: %v\", err)\n}\n// after — verify the endpoint returns real Neutron JSON before extraction\nresp, _ := c.NetworkingClient().Get(ports.List(c.NetworkingClient(), opt).(ports.ListOpts).ToPortsListQuery().(string))\n_ = resp\nr, err := ports.ExtractPorts(allPages)\nif err != nil {\n    return false, fmt.Errorf(\"error extracting ports from pages (check Neutron endpoint/proxy): %v\", err)\n}","handlingStrategy":"type-guard","validationCode":"// Sanity-check that the endpoint speaks Neutron JSON before extracting pages\nresp, err := http.Get(neutronEndpoint + \"/ports?limit=1\")\nif err != nil {\n    return fmt.Errorf(\"cannot reach Neutron: %w\", err)\n}\nct := resp.Header.Get(\"Content-Type\")\nif !strings.Contains(ct, \"application/json\") {\n    return fmt.Errorf(\"endpoint returned %q, not JSON — wrong endpoint or intercepting proxy\", ct)\n}","typeGuard":null,"tryCatchPattern":"ports, err := listPorts(c, opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"error extracting ports from pages\") {\n        // response shape unexpected: verify endpoint URL, proxies, and Neutron version\n        return fmt.Errorf(\"non-JSON or unsupported Neutron response: %w\", err)\n    }\n    return err\n}","preventionTips":["Point the service catalog / OS_* env at the real Neutron endpoint, bypassing proxies.","Pin gophercloud and OpenStack versions with compatible port schemas.","Test the raw endpoint with curl to confirm JSON responses before automated runs.","NO_PROXY should include the OpenStack API hosts to avoid middleware rewriting responses."],"tags":["openstack","neutron","port-list","parsing"],"backgroundTag":"api-response-parse-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}