googleapis/mcp-toolbox · error
failed to unmarshal json: %v
Error message
failed to unmarshal json: %v
What it means
Thrown by the Dgraph source's healthCheck when the /health response body cannot be unmarshaled into the expected JSON array of health entries (instance, address, status). Dgraph returned a 200/body that is not the expected health JSON — often an HTML error page, a proxy message, or an empty body. Wrapped with %v.
Source
Thrown at internal/sources/dgraph/dgraph.go:370
resp, err := hc.httpClient.Do(req)
if err != nil {
return fmt.Errorf("error performing request: %w", err)
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
var result []struct {
Instance string `json:"instance"`
Address string `json:"address"`
Status string `json:"status"`
}
// Unmarshal response into the struct
if err := json.Unmarshal(data, &result); err != nil {
return fmt.Errorf("failed to unmarshal json: %v", err)
}
if len(result) == 0 {
return fmt.Errorf("health info should not empty for: %v", url)
}
var unhealthyErr error
for _, info := range result {
if info.Status != "healthy" {
unhealthyErr = fmt.Errorf("dgraph instance [%v] is not in healthy state, address is %v",
info.Instance, info.Address)
} else {
return nil
}
}
return unhealthyErr
}View on GitHub (pinned to 8cc6e09de2)
Solutions
- curl the exact /health URL and confirm the body is a JSON array like [{"instance":"...","address":"...","status":"healthy"}].
- Ensure baseUrl points at the Dgraph Alpha/Zero HTTP port, not a proxy, UI, or gRPC port.
- Check whether an intermediary (nginx/ingress) is intercepting the request and returning non-JSON responses.
- Verify the Dgraph version still serves the same /health schema.
Example fix
// before: pointing at the UI/proxy baseUrl: http://dgraph-ui:8080 // after: point at the Alpha HTTP endpoint baseUrl: http://dgraph-alpha:8080
Defensive patterns
Strategy: validation
Validate before calling
resp, err := http.Get(baseURL + "/health")
if err != nil { return err }
body, _ := io.ReadAll(resp.Body)
var probe []map[string]interface{}
if err := json.Unmarshal(body, &probe); err != nil {
return fmt.Errorf("/health returned non-JSON body (first 100 bytes: %q) — check for proxy/UI at this address", string(body[:min(100, len(body))]))
} Try / catch
if err := healthCheck(ctx); err != nil {
if strings.Contains(err.Error(), "failed to unmarshal json") {
// non-JSON body: capture the raw response for diagnosis
log.Printf("dgraph /health returned unexpected body; raw: %s", rawBody)
return err
}
return err
} Prevention
- Point baseUrl directly at the Dgraph Alpha/Zero HTTP endpoint, never through a UI or HTML-serving proxy.
- curl the /health endpoint once and confirm the body is a JSON array before configuring.
- Pin and test the Dgraph version; verify the health payload shape after upgrades.
When it happens
Trigger: healthCheck reads the /health response with io.ReadAll and json.Unmarshal(data, &result) fails because the body is not a JSON array of objects with instance/address/status fields (e.g. HTML from a reverse proxy, or a JSON object instead of an array).
Common situations: A load balancer or ingress returns an HTML 502/404 page; pointing baseUrl at the Dgraph HTTP UI or a different service that returns different JSON; a Dgraph version changing the health payload shape.
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
- failed to unmarshal response: %v
- could not unmarshal response as json: %w
- failed to unmarshal operation JSON to map: %w
- error parsing JSON: %v
- error marshlling json: %v
AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05).
Data as JSON: /api/errors/2baeda78e08ee3fc.
Report an issue: GitHub.