{"record":{"id":"f2c439b473c91d9f","repo":"kubernetes/kops","slug":"error-extracting-subnets-from-pages-v","errorCode":null,"errorMessage":"error extracting subnets from pages: %v","messagePattern":"error extracting subnets from pages: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/openstack/subnet.go","lineNumber":44,"sourceCode":"\t\"k8s.io/kops/util/pkg/vfs\"\n)\n\nfunc (c *openstackCloud) ListSubnets(opt subnets.ListOptsBuilder) ([]subnets.Subnet, error) {\n\treturn listSubnets(c, opt)\n}\n\nfunc listSubnets(c OpenstackCloud, opt subnets.ListOptsBuilder) ([]subnets.Subnet, error) {\n\tvar s []subnets.Subnet\n\n\tdone, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {\n\t\tallPages, err := subnets.List(c.NetworkingClient(), opt).AllPages(context.TODO())\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"error listing subnets: %v\", err)\n\t\t}\n\n\t\tr, err := subnets.ExtractSubnets(allPages)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"error extracting subnets from pages: %v\", err)\n\t\t}\n\t\ts = r\n\t\treturn true, nil\n\t})\n\tif err != nil {\n\t\treturn s, err\n\t} else if done {\n\t\treturn s, nil\n\t} else {\n\t\treturn s, wait.ErrWaitTimeout\n\t}\n}\n\nfunc (c *openstackCloud) GetSubnet(subnetID string) (*subnets.Subnet, error) {\n\treturn getSubnet(c, subnetID)\n}\n\nfunc getSubnet(c OpenstackCloud, subnetID string) (*subnets.Subnet, error) {","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/openstack/subnet.go#L26-L62","documentation":"After fetching all pages of subnets from Neutron, kOps calls subnets.ExtractSubnets(allPages) to decode the response bodies. If the pages contain unexpected JSON or an API version mismatch, extraction fails and the error is wrapped as \"error extracting subnets from pages\". This is a response-decoding problem, not a transport problem.","triggerScenarios":"Neutron returns pages in an unexpected format (proxy/intercepting middleware rewriting responses), incompatible gophercloud/openstack SDK vs server API version, or an empty/malformed page body.","commonSituations":"Corporate proxy or service mesh mangling JSON responses, Neutron microversion incompatibility, or SDK upgrade where ExtractSubnets expectations changed.","solutions":["Dump the raw Neutron response (`openstack subnet list --debug`) and compare with what the SDK expects","Pin/upgrade the gophercloud dependency to a version compatible with your OpenStack release","Bypass any proxy/middleware to confirm it is not rewriting responses","Retry once Neutron is confirmed healthy; this error inside RetryWithBackoff surfaces only after retries exhaust"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Compare SDK-extracted output with CLI to detect format drift\nout, _ := exec.Command(\"openstack\", \"subnet\", \"list\", \"--format\", \"json\").Output()\nif len(out) == 0 {\n\tlog.Fatal(\"neutron returned unexpected empty payload\")\n}","typeGuard":null,"tryCatchPattern":"subs, err := listSubnets(cloud, opts)\nif err != nil && strings.Contains(err.Error(), \"extracting subnets from pages\") {\n\t// SDK/Neutron version mismatch: pin gophercloud version and retry\n\treturn err\n}","preventionTips":["Pin gophercloud SDK versions compatible with your OpenStack release","Bypass proxies/interceptors for cloud control-plane traffic","After Neutron upgrades, re-test subnet listing","Log raw response bodies on extraction failures"],"tags":["openstack","neutron","subnet","deserialization"],"backgroundTag":"api-response-deserialization-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}