{"record":{"id":"5ea21607bf4f4621","repo":"kubernetes/kops","slug":"error-extracting-server-groups-from-pages-v","errorCode":null,"errorMessage":"error extracting server groups from pages: %v","messagePattern":"error extracting server groups from pages: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/openstack/server_group.go","lineNumber":74,"sourceCode":"\t}\n}\n\nfunc (c *openstackCloud) ListServerGroups(opts servergroups.ListOptsBuilder) ([]servergroups.ServerGroup, error) {\n\treturn listServerGroups(c, opts)\n}\n\nfunc listServerGroups(c OpenstackCloud, opts servergroups.ListOptsBuilder) ([]servergroups.ServerGroup, error) {\n\tvar sgs []servergroups.ServerGroup\n\n\tdone, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {\n\t\tallPages, err := servergroups.List(c.ComputeClient(), opts).AllPages(context.TODO())\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"error listing server groups: %v\", err)\n\t\t}\n\n\t\tr, err := servergroups.ExtractServerGroups(allPages)\n\t\tif err != nil {\n\t\t\treturn false, fmt.Errorf(\"error extracting server groups from pages: %v\", err)\n\t\t}\n\t\tsgs = r\n\t\treturn true, nil\n\t})\n\tif err != nil {\n\t\treturn sgs, err\n\t} else if done {\n\t\treturn sgs, nil\n\t} else {\n\t\treturn sgs, wait.ErrWaitTimeout\n\t}\n}\n\nfunc osBuildCloudInstanceGroup(c OpenstackCloud, cluster *kops.Cluster, ig *kops.InstanceGroup, nodeMap map[string]*v1.Node) (*cloudinstances.CloudInstanceGroup, error) {\n\tcg := &cloudinstances.CloudInstanceGroup{\n\t\tHumanName:     ig.Name,\n\t\tInstanceGroup: ig,\n\t\tMinSize:       int(fi.ValueOf(ig.Spec.MinSize)),","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/openstack/server_group.go#L56-L92","documentation":"After the pages are fetched, servergroups.ExtractServerGroups(allPages) decodes the JSON body into []servergroups.ServerGroup. If the page body cannot be parsed or does not match the expected server-groups schema, kOps wraps the error as \"error extracting server groups from pages: %v\". This is a response-decoding failure, not a transport failure.","triggerScenarios":"servergroups.ExtractServerGroups(allPages) returns an error because the response body is not valid JSON (truncated page, HTML error page from a proxy), or the JSON lacks the expected \"server_groups\" array / has unexpected field types (e.g. an API microversion or proxy mangling the body).","commonSituations":"An API gateway/LB in front of nova-api returns an HTML 502 page that the SDK tries to unmarshal; a non-standard OpenStack distribution (or older release) returns a different server-groups schema; TLS-terminating proxy truncating large paginated responses; SDK version mismatch with the deployed Nova API.","solutions":["Capture the raw response (e.g. 'openstack server group list --debug') and check whether a proxy/LB is returning an error page instead of JSON.","Upgrade or align the Gophercloud SDK version with the cloud's Nova API release so the schema matches.","Remove/fix any proxy intercepting compute API traffic, or point the client directly at the nova-api endpoint.","Retry if the page was truncated by a transient network error; if consistent, the response schema itself is the problem."],"exampleFix":"// before: incompatible SDK decode of newer API body\n// go.mod: github.com/gophercloud/gophercloud/v2 v2.0.0\n// after: bump SDK to match cloud API\n// go.mod: github.com/gophercloud/gophercloud/v2 v2.x.y (with servergroups schema fix)\nrequire github.com/gophercloud/gophercloud/v2 v2.7.0","handlingStrategy":"fallback","validationCode":"// Probe that the API returns parseable JSON before relying on extraction\nvar probe map[string]json.RawMessage\nresp, err := servergroups.List(computeClient, nil).AllPages(ctx)\nif err == nil {\n\tif err := json.Unmarshal(servergroups.ExtractPagesInto(resp), &probe); err != nil {\n\t\treturn fmt.Errorf(\"compute API returned non-JSON body (proxy misconfiguration?): %w\", err)\n\t}\n}","typeGuard":null,"tryCatchPattern":"sgs, err := cloud.ListServerGroups(opts)\nif err != nil {\n\tif strings.Contains(err.Error(), \"error extracting server groups from pages\") {\n\t\t// decode failure: log raw body via debug mode and degrade gracefully\n\t\tklog.Warningf(\"server group response undecodable; proceeding without server group discovery: %v\", err)\n\t\tsgs = nil // or fall back to an alternate discovery path\n\t\treturn sgs, nil\n\t}\n\treturn err\n}","preventionTips":["Ensure no proxy/LB in front of nova-api returns HTML error pages to API clients.","Keep the Gophercloud SDK version compatible with the cloud's Nova release.","Enable SDK debug logging in staging to catch schema drift early.","Retry on truncated responses caused by transient network errors before diagnosing schema issues."],"tags":["openstack","nova","json-decode","api-compat"],"backgroundTag":"json-unmarshal-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"}