cloudflare/cloudflared · error

the Cloudflare API response was an unexpected type

Error message

the Cloudflare API response was an unexpected type

What it means

parseResponseBody unmarshals the envelope's inner 'result' field into the caller-provided datatype and wraps failures with this message. The outer envelope parsed fine and the API call succeeded, but the result payload does not match the expected Go type (e.g. an object where a list is expected, or a schema change).

Source

Thrown at cfapi/base_client.go:141

	}

	return &result, nil
}

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

	return parseResponseBody(result, data)
}

func parseResponseBody(result *response, data interface{}) error {
	// At this point we know the API call succeeded, so, parse out the inner
	// result into the datatype provided as a parameter.
	if err := json.Unmarshal(result.Result, &data); err != nil {
		return errors.Wrap(err, "the Cloudflare API response was an unexpected type")
	}
	return nil
}

func fetchExhaustively[T any](requestFn func(int) (*http.Response, error)) ([]*T, error) {
	page := 0
	var fullResponse []*T

	for {
		page += 1
		envelope, parsedBody, err := fetchPage[T](requestFn, page)

		if err != nil {
			return nil, errors.Wrap(err, fmt.Sprintf("Error Parsing page %d", page))
		}

		fullResponse = append(fullResponse, parsedBody...)
		if envelope.Pagination.Count < envelope.Pagination.PerPage || len(fullResponse) >= envelope.Pagination.TotalCount {

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Log result.Result raw JSON and compare it to the destination struct's fields/tags.
  2. Upgrade cloudflared/cfapi to the latest version to pick up API schema changes.
  3. Ensure the generic type parameter passed to parseResponse matches the endpoint's result shape.
  4. Check the Cloudflare API changelog for recent changes to the tunnel/teamnet endpoints.

Example fix

// before
var result []cfapi.Route
// after (single-object endpoint)
var result cfapi.Route
Defensive patterns

Strategy: type-guard

Validate before calling

var probe map[string]json.RawMessage
if err := json.Unmarshal(raw, &probe); err != nil {
	return fmt.Errorf("result is not an object: %w", err)
}
if _, ok := probe["result"]; !ok {
	return errors.New("envelope missing result field")
}

Type guard

func isEnvelope(obj map[string]any) bool {
	_, hasSuccess := obj["success"]
	_, hasResult := obj["result"]
	return hasSuccess && hasResult
}

Try / catch

if err := client.SomeCall(t); err != nil {
	if strings.Contains(err.Error(), "unexpected type") {
		return fmt.Errorf("cfapi schema mismatch; upgrade cloudflared: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: The Cloudflare API returns a result whose JSON shape doesn't match the target struct (API schema change, an error object inside result, or the caller passing the wrong type to parseResponse).

Common situations: Using an old cloudflared version against a newer API where the tunnel/route schema changed; passing a single-item struct when the API returns an array (or vice versa).

Related errors


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