{"record":{"id":"45f41a5ea46c5d95","repo":"VictoriaMetrics/VictoriaMetrics","slug":"cannot-parse-nextlink-from-response-q-w","errorCode":null,"errorMessage":"cannot parse nextLink from response %q: %w","messagePattern":"cannot parse nextLink from response %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/promscrape/discovery/azure/machine.go","lineNumber":96,"sourceCode":"\t\t}\n\t\tvar lar listAPIResponse\n\t\tif err := json.Unmarshal(resp, &lar); err != nil {\n\t\t\treturn fmt.Errorf(\"cannot parse azure api response %q obtained from %s: %w\", resp, nextLinkURI, err)\n\t\t}\n\t\tfor i := range lar.Value {\n\t\t\tif err := cb(lar.Value[i]); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\t// Azure API returns NextLink with apiServer in it, so we need to remove it.\n\t\t// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3247\n\t\tif lar.NextLink == \"\" {\n\t\t\tbreak\n\t\t}\n\t\tnextURL, err := url.Parse(lar.NextLink)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot parse nextLink from response %q: %w\", lar.NextLink, err)\n\t\t}\n\n\t\t// Sometimes Azure will respond a host with a port. Since all possible apiServer defined in cloudEnvironments do not include a port,\n\t\t// it is best to check the host without the port. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6912\n\t\tif nextURL.Host != \"\" && nextURL.Hostname() != ac.apiServerHost {\n\t\t\treturn fmt.Errorf(\"unexpected nextLink host %q, expecting %q\", nextURL.Hostname(), ac.apiServerHost)\n\t\t}\n\n\t\tnextLinkURI = nextURL.RequestURI()\n\t}\n\treturn nil\n}\n\n// getVirtualMachines\nfunc getVirtualMachines(ac *apiConfig) ([]virtualMachine, error) {\n\tvms, err := listVMs(ac)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot list virtual machines: %w\", err)","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/VictoriaMetrics/VictoriaMetrics/blob/5079fb58f1e8e62113f90c945ad71586c797d770/lib/promscrape/discovery/azure/machine.go#L78-L114","documentation":"Azure returns a full absolute URL in nextLink for pagination. The code parses it with url.Parse to strip the host (issue #3247). This error is thrown when the nextLink string cannot be parsed as a URL — practically rare, and usually means the API (or an intermediary) returned a malformed or non-URL nextLink value.","triggerScenarios":"url.Parse(lar.NextLink) returns an error for a non-empty nextLink — e.g. control characters, invalid percent-encoding, or a proxy replacing nextLink with something that is not a URL.","commonSituations":"Middleboxes/proxies rewriting response JSON; buggy custom API gateways; malformed continuation tokens surfaced through nextLink.","solutions":["Log the raw nextLink value from the error message and test it with a URL parser","Bypass or fix the proxy rewriting Azure responses","If persistent, capture the full response and report to VictoriaMetrics with the offending nextLink"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isParseableURL(s string) bool {\n    u, err := url.Parse(s)\n    return err == nil && u != nil\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"cannot parse nextLink\") {\n    // capture the raw response for debugging; likely a rewriting proxy\n    return fmt.Errorf(\"azure pagination broken (proxy rewriting nextLink?): %w\", err)\n}","preventionTips":["Audit proxies/gateways for response-body rewriting","Keep VictoriaMetrics updated — nextLink handling has known issue fixes (#3247)"],"tags":["azure","pagination","url-parsing"],"backgroundTag":"malformed-url","analyzedSha":"5079fb58f1e8e62113f90c945ad71586c797d770","analyzedAt":"2026-09-03T18:10:26.153Z","contentChangedAt":"2026-09-03T18:10:26.153Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}