VictoriaMetrics/VictoriaMetrics · error
cannot parse nextLink from response %q: %w
Error message
cannot parse nextLink from response %q: %w
What it means
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.
Source
Thrown at lib/promscrape/discovery/azure/machine.go:96
}
var lar listAPIResponse
if err := json.Unmarshal(resp, &lar); err != nil {
return fmt.Errorf("cannot parse azure api response %q obtained from %s: %w", resp, nextLinkURI, err)
}
for i := range lar.Value {
if err := cb(lar.Value[i]); err != nil {
return err
}
}
// Azure API returns NextLink with apiServer in it, so we need to remove it.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3247
if lar.NextLink == "" {
break
}
nextURL, err := url.Parse(lar.NextLink)
if err != nil {
return fmt.Errorf("cannot parse nextLink from response %q: %w", lar.NextLink, err)
}
// Sometimes Azure will respond a host with a port. Since all possible apiServer defined in cloudEnvironments do not include a port,
// it is best to check the host without the port. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6912
if nextURL.Host != "" && nextURL.Hostname() != ac.apiServerHost {
return fmt.Errorf("unexpected nextLink host %q, expecting %q", nextURL.Hostname(), ac.apiServerHost)
}
nextLinkURI = nextURL.RequestURI()
}
return nil
}
// getVirtualMachines
func getVirtualMachines(ac *apiConfig) ([]virtualMachine, error) {
vms, err := listVMs(ac)
if err != nil {
return nil, fmt.Errorf("cannot list virtual machines: %w", err)View on GitHub (pinned to 5079fb58f1)
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
Defensive patterns
Strategy: type-guard
Type guard
func isParseableURL(s string) bool {
u, err := url.Parse(s)
return err == nil && u != nil
} Try / catch
if err != nil && strings.Contains(err.Error(), "cannot parse nextLink") {
// capture the raw response for debugging; likely a rewriting proxy
return fmt.Errorf("azure pagination broken (proxy rewriting nextLink?): %w", err)
} Prevention
- Audit proxies/gateways for response-body rewriting
- Keep VictoriaMetrics updated — nextLink handling has known issue fixes (#3247)
When it happens
Trigger: 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.
Common situations: Middleboxes/proxies rewriting response JSON; buggy custom API gateways; malformed continuation tokens surfaced through nextLink.
Related errors
- cannot parse MSI endpoint url %q: %w
- unexpected nextLink host %q, expecting %q
- missing directory on the AZBlob container %q
- cannot initialize connection to AZBlob: %w
- failed to create AZBlob service client: %w
AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03).
Data as JSON: /api/errors/45f41a5ea46c5d95.
Report an issue: GitHub.