{"record":{"id":"bbcfa110989d4b6f","repo":"hyperledger/fabric","slug":"error-unmarshalling-json-data","errorCode":null,"errorMessage":"error unmarshalling json data","messagePattern":"error unmarshalling json data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdb.go","lineNumber":896,"sourceCode":"\tif couchdbLogger.IsEnabledFor(zapcore.DebugLevel) {\n\t\tdump, err2 := httputil.DumpResponse(resp, false)\n\t\tif err2 != nil {\n\t\t\tlog.Fatal(err2)\n\t\t}\n\t\t// compact debug log by replacing carriage return / line feed with dashes to separate http headers\n\t\tcouchdbLogger.Debugf(\"[%s] HTTP Response: %s\", dbclient.dbName, bytes.Replace(dump, []byte{0x0d, 0x0a}, []byte{0x20, 0x7c, 0x20}, -1))\n\t}\n\n\t// handle as JSON document\n\tjsonResponseRaw, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, \"\", errors.Wrap(err, \"error reading response body\")\n\t}\n\n\tjsonResponse := &rangeQueryResponse{}\n\terr2 := json.Unmarshal(jsonResponseRaw, &jsonResponse)\n\tif err2 != nil {\n\t\treturn nil, \"\", errors.Wrap(err2, \"error unmarshalling json data\")\n\t}\n\n\t// if an additional record is found, then reduce the count by 1\n\t// and populate the nextStartKey\n\tif jsonResponse.TotalRows > limit {\n\t\tjsonResponse.TotalRows = limit\n\t}\n\n\tcouchdbLogger.Debugf(\"[%s] Total Rows: %d\", dbclient.dbName, jsonResponse.TotalRows)\n\n\t// Use the next endKey as the starting default for the nextStartKey\n\tnextStartKey := endKey\n\n\tfor index, row := range jsonResponse.Rows {\n\n\t\tdocMetadata := &docMetadata{}\n\t\terr3 := json.Unmarshal(row.Doc, &docMetadata)\n\t\tif err3 != nil {","sourceCodeStart":878,"sourceCodeEnd":914,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdb.go#L878-L914","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"resp, err := http.Get(couchURL + \"/_all_docs?limit=1\")\nif err == nil && !isJSONContentType(resp.Header.Get(\"Content-Type\")) {\n    return errors.New(\"endpoint did not return JSON; check proxy/port\")\n}","typeGuard":"func isCouchDBJSON(body []byte) bool {\n    var probe map[string]json.RawMessage\n    return json.Unmarshal(body, &probe) == nil && probe[\"rows\"] != nil\n}","tryCatchPattern":"results, err := db.RangeScan(startKey, endKey)\nvar parseErr *ParseError\nif errors.As(err, &parseErr) || strings.Contains(err.Error(), \"error unmarshalling json data\") {\n    log.Printf(\"non-JSON CouchDB response; dumping endpoint health and proxy logs\")\n}","preventionTips":["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"],"tags":["couchdb","json","unmarshal"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}