{"record":{"id":"616122f892be064e","repo":"hyperledger/fabric","slug":"attempted-to-set-the-batch-size-max-message-count","errorCode":null,"errorMessage":"Attempted to set the batch size max message count to an invalid value: 0","messagePattern":"Attempted to set the batch size max message count to an invalid value: 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/channelconfig/orderer.go","lineNumber":216,"sourceCode":"\treturn capabilities.NewOrdererProvider(oc.protos.Capabilities.Capabilities)\n}\n\nfunc (oc *OrdererConfig) Validate() error {\n\tfor _, validator := range []func() error{\n\t\toc.validateBatchSize,\n\t\toc.validateBatchTimeout,\n\t} {\n\t\tif err := validator(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (oc *OrdererConfig) validateBatchSize() error {\n\tif oc.protos.BatchSize.MaxMessageCount == 0 {\n\t\treturn fmt.Errorf(\"Attempted to set the batch size max message count to an invalid value: 0\")\n\t}\n\tif oc.protos.BatchSize.AbsoluteMaxBytes == 0 {\n\t\treturn fmt.Errorf(\"Attempted to set the batch size absolute max bytes to an invalid value: 0\")\n\t}\n\tif oc.protos.BatchSize.PreferredMaxBytes == 0 {\n\t\treturn fmt.Errorf(\"Attempted to set the batch size preferred max bytes to an invalid value: 0\")\n\t}\n\tif oc.protos.BatchSize.PreferredMaxBytes > oc.protos.BatchSize.AbsoluteMaxBytes {\n\t\treturn fmt.Errorf(\"Attempted to set the batch size preferred max bytes (%v) greater than the absolute max bytes (%v).\", oc.protos.BatchSize.PreferredMaxBytes, oc.protos.BatchSize.AbsoluteMaxBytes)\n\t}\n\treturn nil\n}\n\nfunc (oc *OrdererConfig) validateBatchTimeout() error {\n\tvar err error\n\toc.batchTimeout, err = time.ParseDuration(oc.protos.BatchTimeout.Timeout)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Attempted to set the batch timeout to a invalid value: %s\", err)","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/channelconfig/orderer.go#L198-L234","documentation":"OrdererConfig.Validate() calls validateBatchSize, which requires BatchSize.MaxMessageCount to be non-zero. A value of 0 would allow batches of unlimited/unusable message counts, so the library rejects it during orderer config validation. This is a semantic validation of the ab.BatchSize proto decoded from the Orderer group.","triggerScenarios":"Calling NewOrdererConfig (via NewChannelConfig, or TestBatchSize in tests) with an orderer group whose BatchSize value has MaxMessageCount == 0 — typically because the BatchSize proto was left as a zero-valued struct or only partially populated.","commonSituations":"Generating channel config programmatically and forgetting to set MaxMessageCount; configtx profiles omitting BatchSize so defaults are never applied; test fixtures constructing ab.BatchSize{} empty; configtxlator edits that zero out the field.","solutions":["Set MaxMessageCount to a positive integer (e.g. 500, the Fabric default) in the channel profile's Orderer.BatchSize section and regenerate the config.","If constructing ab.BatchSize in code, populate MaxMessageCount before marshaling into the ConfigValue.","If BatchSize is missing entirely, add the full BatchSize block (MaxMessageCount, AbsoluteMaxBytes, PreferredMaxBytes) to the configtx profile.","In tests, use a populated BatchSize fixture before calling the validation path."],"exampleFix":"// before (configtx.yaml)\nOrderer:\n  BatchSize:\n    AbsoluteMaxBytes: 10 MB\n    PreferredMaxBytes: 2 MB\n// after\nOrderer:\n  BatchSize:\n    MaxMessageCount: 500\n    AbsoluteMaxBytes: 10 MB\n    PreferredMaxBytes: 2 MB","handlingStrategy":"validation","validationCode":"func checkBatchSize(bs *ab.BatchSize) error {\n\tif bs == nil || bs.MaxMessageCount == 0 {\n\t\treturn errors.New(\"BatchSize.MaxMessageCount must be a positive integer (e.g. 500)\")\n\t}\n\treturn nil\n}","typeGuard":"func hasValidMaxMessageCount(bs *ab.BatchSize) bool {\n\treturn bs != nil && bs.MaxMessageCount > 0\n}","tryCatchPattern":"_, err := channelconfig.NewChannelConfig(env.Config)\nif err != nil {\n\tif strings.Contains(err.Error(), \"max message count to an invalid value: 0\") {\n\t\treturn fmt.Errorf(\"fix Orderer.BatchSize.MaxMessageCount in configtx.yaml (set to e.g. 500) and regenerate: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Always include MaxMessageCount in the Orderer.BatchSize section of configtx.yaml profiles.","Use Fabric defaults (MaxMessageCount: 500) as a starting point.","Never construct ab.BatchSize without setting all three fields.","Run configtxgen to validate the profile before channel creation."],"tags":["hyperledger-fabric","channel-config","validation","batch-size","configtx"],"backgroundTag":"invalid-config-value","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"}