{"record":{"id":"e69f04206a5f5332","repo":"hyperledger/fabric","slug":"attempted-to-set-the-batch-size-preferred-max-byte","errorCode":null,"errorMessage":"Attempted to set the batch size preferred max bytes to an invalid value: 0","messagePattern":"Attempted to set the batch size preferred max bytes to an invalid value: 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/channelconfig/orderer.go","lineNumber":222,"sourceCode":"\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)\n\t}\n\tif oc.batchTimeout <= 0 {\n\t\treturn fmt.Errorf(\"Attempted to set the batch timeout to a non-positive value: %s\", oc.batchTimeout)\n\t}\n\treturn nil\n}","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/channelconfig/orderer.go#L204-L240","documentation":"validateBatchSize requires BatchSize.PreferredMaxBytes to be non-zero; PreferredMaxBytes is the soft target batch size the orderer cuts a block at, and 0 is considered invalid, so orderer config validation fails. This runs as part of OrdererConfig.Validate whenever the orderer group is processed.","triggerScenarios":"Calling NewOrdererConfig with an orderer group whose BatchSize value has PreferredMaxBytes == 0 — an empty/partially populated ab.BatchSize proto or a configtx profile missing the PreferredMaxBytes field.","commonSituations":"configtx.yaml Orderer.BatchSize omitting PreferredMaxBytes while setting the other two fields; programmatic config generation with a partially filled struct; configtxlator edits that drop the field; test fixtures with zero-valued BatchSize.","solutions":["Set PreferredMaxBytes to a positive value (Fabric default 2097152, i.e. 2 MB) in Orderer.BatchSize and regenerate the config.","Keep PreferredMaxBytes <= AbsoluteMaxBytes to also pass the ordering check that follows.","When constructing ab.BatchSize in code, set all three fields before marshaling.","Validate the profile with configtxgen before channel creation/update."],"exampleFix":"// before (configtx.yaml)\nOrderer:\n  BatchSize:\n    MaxMessageCount: 500\n    AbsoluteMaxBytes: 10 MB\n// after\nOrderer:\n  BatchSize:\n    MaxMessageCount: 500\n    AbsoluteMaxBytes: 10 MB\n    PreferredMaxBytes: 2 MB","handlingStrategy":"validation","validationCode":"func checkPreferredMaxBytes(bs *ab.BatchSize) error {\n\tif bs == nil || bs.PreferredMaxBytes == 0 {\n\t\treturn errors.New(\"BatchSize.PreferredMaxBytes must be positive (e.g. 2097152 for 2 MB)\")\n\t}\n\tif bs.PreferredMaxBytes > bs.AbsoluteMaxBytes {\n\t\treturn errors.New(\"BatchSize.PreferredMaxBytes must not exceed AbsoluteMaxBytes\")\n\t}\n\treturn nil\n}","typeGuard":"func hasValidPreferredMaxBytes(bs *ab.BatchSize) bool {\n\treturn bs != nil && bs.PreferredMaxBytes > 0 && bs.PreferredMaxBytes <= bs.AbsoluteMaxBytes\n}","tryCatchPattern":"_, err := channelconfig.NewChannelConfig(env.Config)\nif err != nil {\n\tif strings.Contains(err.Error(), \"preferred max bytes to an invalid value: 0\") {\n\t\treturn fmt.Errorf(\"set Orderer.BatchSize.PreferredMaxBytes (default 2 MB, <= AbsoluteMaxBytes) and regenerate: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Include PreferredMaxBytes in every Orderer.BatchSize profile (default 2 MB).","Keep PreferredMaxBytes <= AbsoluteMaxBytes to pass the ordering check.","Set all three BatchSize fields as a group; never build a partial ab.BatchSize.","Run configtxgen validation before channel creation or config updates."],"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"}