hyperledger/fabric · error
error unmarshalling json data
Error message
error unmarshalling json data
What it means
Returned when json.Unmarshal fails to decode the raw response body into the rangeQueryResponse struct during a CouchDB range query. It means the server responded with bytes that are not the expected JSON shape — typically an HTML/empty/proxy error body instead of CouchDB's {total_rows, offset, rows} JSON.
Source
Thrown at core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdb.go:896
if couchdbLogger.IsEnabledFor(zapcore.DebugLevel) {
dump, err2 := httputil.DumpResponse(resp, false)
if err2 != nil {
log.Fatal(err2)
}
// compact debug log by replacing carriage return / line feed with dashes to separate http headers
couchdbLogger.Debugf("[%s] HTTP Response: %s", dbclient.dbName, bytes.Replace(dump, []byte{0x0d, 0x0a}, []byte{0x20, 0x7c, 0x20}, -1))
}
// handle as JSON document
jsonResponseRaw, err := io.ReadAll(resp.Body)
if err != nil {
return nil, "", errors.Wrap(err, "error reading response body")
}
jsonResponse := &rangeQueryResponse{}
err2 := json.Unmarshal(jsonResponseRaw, &jsonResponse)
if err2 != nil {
return nil, "", errors.Wrap(err2, "error unmarshalling json data")
}
// if an additional record is found, then reduce the count by 1
// and populate the nextStartKey
if jsonResponse.TotalRows > limit {
jsonResponse.TotalRows = limit
}
couchdbLogger.Debugf("[%s] Total Rows: %d", dbclient.dbName, jsonResponse.TotalRows)
// Use the next endKey as the starting default for the nextStartKey
nextStartKey := endKey
for index, row := range jsonResponse.Rows {
docMetadata := &docMetadata{}
err3 := json.Unmarshal(row.Doc, &docMetadata)
if err3 != nil {View on GitHub (pinned to 2736b63f8f)
Solutions
- Log/inspect the response body (peer debug logging dumps it) to see what was actually returned.
- Verify the configured address really points to CouchDB (curl the /_all_docs endpoint manually).
- Check proxy/load-balancer error pages and increase proxy timeouts so real JSON is returned.
- Retry after confirming CouchDB is healthy; check couchdb logs for 5xx responses.
Defensive patterns
Strategy: try-catch
Validate before calling
resp, err := http.Get(couchURL + "/_all_docs?limit=1")
if err == nil && !isJSONContentType(resp.Header.Get("Content-Type")) {
return errors.New("endpoint did not return JSON; check proxy/port")
} Type guard
func isCouchDBJSON(body []byte) bool {
var probe map[string]json.RawMessage
return json.Unmarshal(body, &probe) == nil && probe["rows"] != nil
} Try / catch
results, err := db.RangeScan(startKey, endKey)
var parseErr *ParseError
if errors.As(err, &parseErr) || strings.Contains(err.Error(), "error unmarshalling json data") {
log.Printf("non-JSON CouchDB response; dumping endpoint health and proxy logs")
} Prevention
- Confirm port 5984 actually serves CouchDB (curl / returns couchdb welcome JSON)
- Configure proxies to pass CouchDB error bodies through instead of HTML pages
- Enable peer debug logging to capture dumped HTTP responses
- Alert on CouchDB 5xx rates to catch degradation early
When it happens
Trigger: handleRangeQuery GET succeeds at HTTP level but the body is not valid JSON: CouchDB returned an error page, an empty body from an interrupted proxy, or a non-CouchDB service answered on the port.
Common situations: Reverse proxy (nginx/HAProxy) returning HTML 502/504 pages, something else listening on port 5984, TLS proxy mangling responses, or CouchDB returning truncated bodies under memory pressure.
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
- too few arguments
- Failed opening file %s: %v
- config isn't valid
- error unmarshalling json data
- incorrect number of arguments
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/bbcfa110989d4b6f.
Report an issue: GitHub.