cloudflare/cloudflared · error

failed to decode response

Error message

failed to decode response

What it means

parseResponseEnvelope decodes the Cloudflare API response JSON envelope ({success, errors, messages, result}) and wraps json decode failures with this message. It means the response body was not valid JSON at all — the API (or an intermediary) returned HTML, an empty body, or truncated output.

Source

Thrown at cfapi/base_client.go:116

	if err != nil {
		return nil, errors.Wrapf(err, "can't create %s request", method)
	}
	req.Header.Set("User-Agent", r.userAgent)
	if bodyReader != nil {
		req.Header.Set("Content-Type", jsonContentType)
	}
	req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", r.authToken))
	req.Header.Add("Accept", "application/json;version=1")
	return r.client.Do(req)
}

func parseResponseEnvelope(reader io.Reader) (*response, error) {
	// Schema for Tunnelstore responses in the v1 API.
	// Roughly, it's a wrapper around a particular result that adds failures/errors/etc
	var result response
	// First, parse the wrapper and check the API call succeeded
	if err := json.NewDecoder(reader).Decode(&result); err != nil {
		return nil, errors.Wrap(err, "failed to decode response")
	}
	if err := result.checkErrors(); err != nil {
		return nil, err
	}
	if !result.Success {
		return nil, ErrAPINoSuccess
	}

	return &result, nil
}

func parseResponse(reader io.Reader, data interface{}) error {
	result, err := parseResponseEnvelope(reader)
	if err != nil {
		return err
	}

	return parseResponseBody(result, data)

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Log the raw response body and status code to see what was actually returned.
  2. Verify you are reaching https://api.cloudflare.com and not a captive portal or proxy error page.
  3. Retry the request — transient network truncation is a common cause.
  4. If behind a corporate proxy, whitelist the API host or bypass the proxy for it.
Defensive patterns

Strategy: retry

Try / catch

var resp *cfapi.Route
err := retry(3, backoff, func() error {
	var err error
	resp, err = client.GetRouteByIP(ctx, ip)
	return err
})
if err != nil {
	log.Error().Err(err).Msg("cfapi call failed after retries")
}

Prevention

When it happens

Trigger: Receiving an HTML error page from a proxy/CDN, an empty response, a truncated body from network interruption, or hitting a non-Cloudflare-API endpoint that returns non-JSON.

Common situations: Corporate proxies or auth walls returning HTML login pages, Cloudflare WAF challenges, API downtime returning an error page, or TLS-intercepting middleboxes mangling responses.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/3abec8b243447e9f. Report an issue: GitHub.