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

  1. Log the raw nextLink value from the error message and test it with a URL parser
  2. Bypass or fix the proxy rewriting Azure responses
  3. 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

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


AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03). Data as JSON: /api/errors/45f41a5ea46c5d95. Report an issue: GitHub.