{"record":{"id":"1696e674bb9476bf","repo":"hyperledger/fabric","slug":"config-validation-failed","errorCode":null,"errorMessage":"config validation failed","messagePattern":"config validation failed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/util/util.go","lineNumber":68,"sourceCode":"\t\treturn config, errors.Wrap(err, \"bad config metadata option LeaderHeartbeatTimeout\")\n\t}\n\tconfig.LeaderHeartbeatCount = options.LeaderHeartbeatCount\n\tif config.CollectTimeout, err = time.ParseDuration(options.CollectTimeout); err != nil {\n\t\treturn config, errors.Wrap(err, \"bad config metadata option CollectTimeout\")\n\t}\n\tconfig.SyncOnStart = options.SyncOnStart\n\tconfig.SpeedUpViewChange = options.SpeedUpViewChange\n\n\tif options.LeaderRotation != smartbft.Options_ROTATION_ON {\n\t\tconfig.LeaderRotation = false\n\t\tconfig.DecisionsPerLeader = 0\n\t} else {\n\t\tconfig.LeaderRotation = true\n\t\tconfig.DecisionsPerLeader = options.DecisionsPerLeader\n\t}\n\n\tif err = config.Validate(); err != nil {\n\t\treturn config, errors.Wrap(err, \"config validation failed\")\n\t}\n\n\tif options.RequestMaxBytes == 0 {\n\t\tconfig.RequestMaxBytes = config.RequestBatchMaxBytes\n\t} else {\n\t\tconfig.RequestMaxBytes = options.RequestMaxBytes\n\t}\n\n\treturn config, nil\n}\n","sourceCodeStart":50,"sourceCodeEnd":79,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/util/util.go#L50-L79","documentation":"After parsing all metadata options into a types.Configuration, ConfigFromMetadataOptions calls config.Validate(); if any invariant is violated (inconsistent timeouts, zero thresholds, etc.) the error is wrapped as 'config validation failed'. This guards against syntactically valid but semantically unsafe BFT configurations before the chain is started.","triggerScenarios":"Orderer start, channel config commit, or `inspect` when individual durations parse but violate validation rules — e.g. ViewChangeResendInterval >= ViewChangeTimeout, LeaderHeartbeatCount 0, RequestBatchMaxCount 0, or timeout hierarchy inversions.","commonSituations":"Operator tuned one timeout without respecting required relationships to the others, copied options from a Raft config, or a tool generated options with zero-value numeric fields.","solutions":["Read the wrapped underlying error to see which validation invariant failed and adjust the offending option","Ensure timeout hierarchy holds (e.g. resend interval < view change timeout, heartbeat timeouts consistent)","Set all numeric options to nonzero sane values matching the official BFT config guidance","Use `inspect` to validate the config block before committing the update"],"exampleFix":"// before\n\"ViewChangeResendInterval\": \"30s\",\n\"ViewChangeTimeout\": \"20s\" // validation fails: resend >= timeout\n// after\n\"ViewChangeResendInterval\": \"10s\",\n\"ViewChangeTimeout\": \"20s\"","handlingStrategy":"validation","validationCode":"cfg, err := util.ConfigFromMetadataOptions(selfID, opts)\nif err != nil { return fmt.Errorf(\"options fail validation: %w\", err) }\n// additionally: resend < viewChange, heartbeat count > 0 checks","typeGuard":null,"tryCatchPattern":"cfg, err := util.ConfigFromMetadataOptions(selfID, opts)\nif err != nil {\n  if strings.Contains(err.Error(), \"config validation failed\") {\n    return fmt.Errorf(\"BFT options semantically invalid, fix options and resubmit: %w\", err)\n  }\n  return err\n}","preventionTips":["Change one BFT timeout at a time and re-validate relationships","Keep documented default values unless tuning is required","Use inspect to validate the whole config block pre-commit","Don't copy Raft timing options into BFT metadata"],"tags":["hyperledger-fabric","config","smartbft","validation"],"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"}