{"record":{"id":"3e77405d2768a672","repo":"hyperledger/fabric","slug":"could-not-parse-the-collection-configuration","errorCode":null,"errorMessage":"could not parse the collection configuration","messagePattern":"could not parse the collection configuration","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/chaincode/common.go","lineNumber":183,"sourceCode":"// from the supplied file; the supplied file must contain a\n// json-formatted array of collectionConfigJson elements\nfunc GetCollectionConfigFromFile(ccFile string) (*pb.CollectionConfigPackage, []byte, error) {\n\tfileBytes, err := os.ReadFile(ccFile)\n\tif err != nil {\n\t\treturn nil, nil, errors.Wrapf(err, \"could not read file '%s'\", ccFile)\n\t}\n\n\treturn getCollectionConfigFromBytes(fileBytes)\n}\n\n// getCollectionConfigFromBytes retrieves the collection configuration\n// from the supplied byte array; the byte array must contain a\n// json-formatted array of collectionConfigJson elements\nfunc getCollectionConfigFromBytes(cconfBytes []byte) (*pb.CollectionConfigPackage, []byte, error) {\n\tcconf := &[]collectionConfigJson{}\n\terr := json.Unmarshal(cconfBytes, cconf)\n\tif err != nil {\n\t\treturn nil, nil, errors.Wrap(err, \"could not parse the collection configuration\")\n\t}\n\n\tccarray := make([]*pb.CollectionConfig, 0, len(*cconf))\n\tfor _, cconfitem := range *cconf {\n\t\tp, err := policydsl.FromString(cconfitem.Policy)\n\t\tif err != nil {\n\t\t\treturn nil, nil, errors.WithMessagef(err, \"invalid policy %s\", cconfitem.Policy)\n\t\t}\n\n\t\tcpc := &pb.CollectionPolicyConfig{\n\t\t\tPayload: &pb.CollectionPolicyConfig_SignaturePolicy{\n\t\t\t\tSignaturePolicy: p,\n\t\t\t},\n\t\t}\n\n\t\tvar ep *pb.ApplicationPolicy\n\t\tif cconfitem.EndorsementPolicy != nil {\n\t\t\tsignaturePolicy := cconfitem.EndorsementPolicy.SignaturePolicy","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/chaincode/common.go#L165-L201","documentation":"getCollectionConfigFromBytes parses a JSON array of collection config entries (collectionConfigJson) into a protobuf CollectionConfigPackage. When json.Unmarshal fails because the bytes are not valid JSON or don't match the expected schema (array of objects with name, policy, requiredPeerCount, etc.), the error is wrapped as \"could not parse the collection configuration\". This signals the caller supplied a malformed collection configuration file or byte payload.","triggerScenarios":"Calling GetCollectionConfigFromFile with a file containing invalid JSON, or passing bytes that are a single JSON object instead of an array, or entries missing/misspelling required fields (e.g. \"name\", \"policy\"), so json.Unmarshal into []collectionConfigJson fails.","commonSituations":"Hand-writing private data collection JSON files for chaincode endorsement policies (typos, trailing commas, YAML pasted instead of JSON), stale config from a prior Fabric version with a different schema, or passing a collection config meant for another format.","solutions":["Validate the collection config file with 'jq . collections.json' to confirm it is a JSON array of objects","Ensure the file matches the collectionConfigJson schema: an array with objects containing name, policy, requiredPeerCount, maxPeerCount, and optional blockToLive/memberOnlyReads fields","Check file encoding (UTF-8, no BOM) and remove trailing commas or comments","Regenerate the config from the Fabric sample templates to match your Fabric version's schema"],"exampleFix":"// before (invalid: object, not array)\n{\"name\":\"col1\",\"policy\":\"OR('Org1MSP.member')\"}\n// after\n[{\"name\":\"col1\",\"policy\":\"OR('Org1MSP.member')\",\"requiredPeerCount\":1,\"maxPeerCount\":2,\"blockToLive\":0}]","handlingStrategy":"validation","validationCode":"cfg, err := os.ReadFile(\"collections.json\")\nif err != nil { return err }\nvar entries []map[string]any\nif err := json.Unmarshal(cfg, &entries); err != nil { return fmt.Errorf(\"collections.json is not valid JSON array: %w\", err) }\nfor _, e := range entries {\n\tif _, ok := e[\"name\"].(string); !ok { return errors.New(\"collection entry missing name\") }\n\tif _, ok := e[\"policy\"].(string); !ok { return errors.New(\"collection entry missing policy\") }\n}","typeGuard":"func isValidCollectionConfig(b []byte) bool {\n\tvar c []map[string]any\n\treturn json.Unmarshal(b, &c) == nil && len(c) > 0\n}","tryCatchPattern":"ccp, _, err := getCollectionConfigFromBytes(cconfBytes)\nif err != nil {\n\tvar syntaxErr *json.SyntaxError\n\tif errors.As(err, &syntaxErr) { log.Fatalf(\"malformed JSON at offset %d: %v\", syntaxErr.Offset, syntaxErr) }\n\treturn fmt.Errorf(\"check collection config file: %w\", err)\n}","preventionTips":["Run 'jq .' on the collection config file before every deploy","Keep a validated sample collections.json in your repo and diff against it","Use jsonschema tooling to lint collection configs in CI"],"tags":["json","chaincode","config-parsing","fabric"],"backgroundTag":"json-parse-error","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"}