{"record":{"id":"61021d850bd7cf96","repo":"kubernetes/kops","slug":"fetching-metadata-from-s-returned-status-code","errorCode":null,"errorMessage":"fetching metadata from '%s' returned status code '%d'","messagePattern":"fetching metadata from '(.+?)' returned status code '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/openstack/openstackmetadata/metadata.go","lineNumber":150,"sourceCode":"\treturn mds.parseMetadata(f)\n}\n\n// getFromMetadataService tries to get metadata from a metadata service endpoint and returns it as InstanceMetadata.\n// If the service endpoint cannot be contacted or reports a different status than StatusOK it will return an error.\nfunc (mds MetadataService) getFromMetadataService() (*InstanceMetadata, error) {\n\tvar client http.Client\n\n\tresp, err := client.Get(mds.serviceURL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusOK {\n\t\treturn mds.parseMetadata(resp.Body)\n\t}\n\n\terr = fmt.Errorf(\"fetching metadata from '%s' returned status code '%d'\", mds.serviceURL, resp.StatusCode)\n\treturn nil, err\n}\n\n// parseMetadata reads JSON data from a Reader and returns it as InstanceMetadata.\nfunc (mds MetadataService) parseMetadata(r io.Reader) (*InstanceMetadata, error) {\n\tvar meta InstanceMetadata\n\n\tdata, err := io.ReadAll(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = json.Unmarshal(data, &meta)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &meta, nil\n}","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/openstack/openstackmetadata/metadata.go#L132-L168","documentation":"getFromMetadataService (upup/pkg/fi/cloudup/openstack/openstackmetadata/metadata.go:150) performs an HTTP GET against mds.serviceURL (the OpenStack metadata service). Only HTTP 200 is treated as success; any other status code produces this error including the URL and code.","triggerScenarios":"The HTTP request to the metadata service completes but returns a status other than 200 — 404 when the route is absent, 401/403 on gated metadata, 429 on throttling, or 5xx from the nova-api-metadata side.","commonSituations":"Instance not on a network with the metadata service route (169.254.169.254 redirected incorrectly); a proxy intercepting metadata requests and returning an error page; overloaded nova-metadata returning 500s; older clouds lacking a requested metadata path.","solutions":["Check the exact status code in the message and correlate with the metadata service logs (nova-api-metadata).","Verify the instance network routes 169.254.169.254 to the metadata service (no interfering proxy, correct iptables/ dnsmasq rules).","Retry the request — 429/5xx are often transient; getMetadata may already retry via search order.","Fall back to config-drive metadata by configuring the search order to include ConfigDriveID."],"exampleFix":"// before\nif resp.StatusCode == http.StatusOK {\n    return mds.parseMetadata(resp.Body)\n}\nerr = fmt.Errorf(\"fetching metadata from '%s' returned status code '%d'\", mds.serviceURL, resp.StatusCode)\n// after — include the body for diagnosis\nif resp.StatusCode == http.StatusOK {\n    return mds.parseMetadata(resp.Body)\n}\nbody, _ := io.ReadAll(io.LimitReader(resp.Body, 512))\nerr = fmt.Errorf(\"fetching metadata from '%s' returned status code '%d': %s\", mds.serviceURL, resp.StatusCode, string(body))","handlingStrategy":"retry","validationCode":"// Probe the metadata service before relying on it\nresp, err := http.Get(\"http://169.254.169.254/openstack/latest/meta_data.json\")\nif err != nil {\n    return errors.New(\"metadata service unreachable at 169.254.169.254\")\n}\nif resp.StatusCode != http.StatusOK {\n    return fmt.Errorf(\"metadata service returned %d; check nova-api-metadata health\", resp.StatusCode)\n}","typeGuard":null,"tryCatchPattern":"meta, err := mds.getFromMetadataService()\nif err != nil {\n    var statusErr interface{ Error() string }\n    if errors.As(err, &statusErr) && strings.Contains(err.Error(), \"status code '5\") {\n        // 5xx from metadata service — retry with backoff\n        time.Sleep(2 * time.Second)\n        return mds.getFromMetadataService()\n    }\n    return nil, err\n}","preventionTips":["Ensure the instance network routes 169.254.169.254 to the metadata service with no proxy interference.","Exclude the metadata IP from HTTP_PROXY / NO_PROXY settings on instances.","Monitor nova-api-metadata health in the cloud; 5xx usually means the service is overloaded.","Configure config-drive as an alternative source in the search order."],"tags":["openstack","metadata-service","http","network"],"backgroundTag":"metadata-service-http-error","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"}