hyperledger/fabric · error

error unmarshalling json data

Error message

error unmarshalling json data

What it means

castToJSON unmarshals raw bytes into a map[string]any jsonValue and wraps any json.Unmarshal failure with "error unmarshalling json data". It is used by removeJSONRevision to strip the _rev field from retrieved CouchDB documents, so the error means a document's stored bytes are not a valid JSON object. Note the current implementation returns the (possibly nil) jsonVal along with a non-nil wrapped error.

Source

Thrown at core/ledger/kvledger/txmgmt/statedb/statecouchdb/couchdoc_conv.go:46

type keyValue struct {
	key      string
	revision string
	*statedb.VersionedValue
}

type jsonValue map[string]any

func tryCastingToJSON(b []byte) (isJSON bool, val jsonValue) {
	var jsonVal map[string]any
	err := json.Unmarshal(b, &jsonVal)
	return err == nil, jsonVal
}

func castToJSON(b []byte) (jsonValue, error) {
	var jsonVal map[string]any
	err := json.Unmarshal(b, &jsonVal)
	err = errors.Wrap(err, "error unmarshalling json data")
	return jsonVal, err
}

func (v jsonValue) checkReservedFieldsNotPresent() error {
	for fieldName := range v {
		if fieldName == versionField || strings.HasPrefix(fieldName, "_") {
			return errors.Errorf("field [%s] is not valid for the CouchDB state database", fieldName)
		}
	}
	return nil
}

func (v jsonValue) removeRevField() {
	delete(v, revField)
}

func (v jsonValue) toBytes() ([]byte, error) {
	jsonBytes, err := json.Marshal(v)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Inspect the offending CouchDB document (curl GET /dbname/docid) and verify it is a valid JSON object.
  2. Restore corrupted documents from a backup or rebuild the state database (drop and re-read from the blockchain).
  3. Ensure only the peer writes to CouchDB — external modifications can introduce non-object documents.

Example fix

// before: doc stored as non-object JSON
{"_id":"x"}  // OK
// a document stored as "just a string" fails; rewrite it as an object:
curl -X PUT https://admin:pass@localhost:5984/db/x -d '{"_id":"x","data":"value"}'
Defensive patterns

Strategy: type-guard

Validate before calling

// verify stored document is a JSON object before processing
var probe map[string]any
if err := json.Unmarshal(docBytes, &probe); err != nil || probe == nil { /* corrupt or non-object document */ }

Type guard

func isJSONMap(b []byte) bool {
    var m map[string]any
    return json.Unmarshal(b, &m) == nil && m != nil
}

Try / catch

jsonVal, err := castToJSON(b)
if err != nil {
    if strings.Contains(err.Error(), "error unmarshalling json data") {
        // restore from backup or rebuild state db for this document
    }
    return err
}

Prevention

When it happens

Trigger: removeJSONRevision processing a CouchDB document whose jsonValue bytes fail to parse as a JSON object — e.g. the stored value is null, a scalar/array, or truncated bytes.

Common situations: Corrupted CouchDB documents; documents written directly to CouchDB externally in a non-object JSON form; version mismatch where an older Fabric wrote data in a shape the current code cannot parse.

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 hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/cd1d3177446c4eff. Report an issue: GitHub.