hyperledger/fabric · error
failed to marshal config
Error message
failed to marshal config
What it means
batchUpdateDocuments() assembles documentMap["docs"] (the array of per-document maps) and marshals it into the _bulk_docs request body with json.Marshal. Failure is wrapped as 'error marshalling json data' and the batch write is aborted. Since inputs are already decoded into plain maps/slices, failure indicates some document map still contains values Go cannot encode (channels, funcs, cycles, unsupported types).
Source
Thrown at cmd/common/config.go:47
return Config{}, errors.WithStack(err)
}
config := Config{}
if err := yaml.Unmarshal(configData, &config); err != nil {
return Config{}, errors.Errorf("error unmarshalling YAML file %s: %s", file, err)
}
return config, validateConfig(config)
}
// ToFile writes the config into a file
func (c Config) ToFile(file string) error {
if err := validateConfig(c); err != nil {
return errors.Wrap(err, "config isn't valid")
}
b, err := yaml.Marshal(c)
if err != nil {
return errors.Wrap(err, "failed to marshal config")
}
if err := os.WriteFile(file, b, 0o600); err != nil {
return errors.Errorf("failed writing file %s: %v", file, err)
}
return nil
}
func validateConfig(conf Config) error {
nonEmptyElems := map[string]string{
"MSPID": conf.SignerConfig.MSPID,
"IdentityPath": conf.SignerConfig.IdentityPath,
"KeyPath": conf.SignerConfig.KeyPath,
}
for key, value := range nonEmptyElems {
if value == "" {
return errors.Errorf("%s is mandatory and cannot be empty", key)
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Marshal each document map individually in a loop to isolate the failing key and underlying error
- Strip/fix non-serializable values before adding to jsonDocumentMap
- Ensure attachments use the proper *Attachment struct, not raw unsupported types
- Verify against stock Fabric — the stock pipeline marshals only plain maps/strings/[]byte and should never fail
- Add a pre-flight json.Marshal check and skip/log offending documents rather than failing the whole batch
Example fix
// before
documentMap["docs"] = jsonDocumentMap
bulkDocsJSON, err := json.Marshal(documentMap) // fails on one bad doc
// after
for i, doc := range jsonDocumentMap {
if _, e := json.Marshal(doc); e != nil {
return nil, fmt.Errorf("document %d not marshallable: %w", i, e)
}
}
bulkDocsJSON, err := json.Marshal(documentMap) Defensive patterns
Strategy: validation
Validate before calling
if _, err := json.Marshal(documentMap); err != nil {
return fmt.Errorf("bulk docs payload not marshallable: %w", err)
} Try / catch
if err != nil && strings.Contains(err.Error(), "error marshalling json data") {
return fmt.Errorf("_bulk_docs payload invalid — inspect document maps: %w", err)
} Prevention
- Keep per-document maps composed of encodable primitives and []byte
- Use the standard *Attachment struct for attachments
- Unit-test batch assembly with json.Marshal
- Avoid fork changes to document map construction
- Marshal each doc individually when debugging to isolate the offender
When it happens
Trigger: A batch write where one or more per-document maps (or their attachment structures) contain non-encodable values after unmarshal+merge — usually only possible via modified code paths or attachment metadata with unsupported types.
Common situations: Custom attachments handling that inserts unsupported types into the map, forks altering document construction, cyclic references introduced by custom data flowing into the document map.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- incorrect number of arguments
- connection.json not found in source folder: %s
- too few arguments
- Failed opening file %s: %v
- config isn't valid
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/8b7372a2ffa6584e.
Report an issue: GitHub.