{"record":{"id":"b70d1904eb031327","repo":"hyperledger/fabric","slug":"bad-config-metadata-option-leaderheartbeattimeout","errorCode":null,"errorMessage":"bad config metadata option LeaderHeartbeatTimeout","messagePattern":"bad config metadata option LeaderHeartbeatTimeout","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/util/util.go","lineNumber":50,"sourceCode":"\tconfig.IncomingMessageBufferSize = options.IncomingMessageBufferSize\n\tconfig.RequestPoolSize = options.RequestPoolSize\n\tif config.RequestForwardTimeout, err = time.ParseDuration(options.RequestForwardTimeout); err != nil {\n\t\treturn config, errors.Wrap(err, \"bad config metadata option RequestForwardTimeout\")\n\t}\n\tif config.RequestComplainTimeout, err = time.ParseDuration(options.RequestComplainTimeout); err != nil {\n\t\treturn config, errors.Wrap(err, \"bad config metadata option RequestComplainTimeout\")\n\t}\n\tif config.RequestAutoRemoveTimeout, err = time.ParseDuration(options.RequestAutoRemoveTimeout); err != nil {\n\t\treturn config, errors.Wrap(err, \"bad config metadata option RequestAutoRemoveTimeout\")\n\t}\n\tif config.ViewChangeResendInterval, err = time.ParseDuration(options.ViewChangeResendInterval); err != nil {\n\t\treturn config, errors.Wrap(err, \"bad config metadata option ViewChangeResendInterval\")\n\t}\n\tif config.ViewChangeTimeout, err = time.ParseDuration(options.ViewChangeTimeout); err != nil {\n\t\treturn config, errors.Wrap(err, \"bad config metadata option ViewChangeTimeout\")\n\t}\n\tif config.LeaderHeartbeatTimeout, err = time.ParseDuration(options.LeaderHeartbeatTimeout); err != nil {\n\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\")","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/util/util.go#L32-L68","documentation":"ConfigFromMetadataOptions parses LeaderHeartbeatTimeout from the BFT metadata options with time.ParseDuration; on failure it returns this wrapped error. The leader heartbeat timeout controls liveness detection in SmartBFT, so an unparseable value aborts chain creation or the config-block commit.","triggerScenarios":"Orderer HandleChain startup, configBlockToBFTConfig during channel update, or `inspect` when options.LeaderHeartbeatTimeout is absent, empty, or not a valid duration string.","commonSituations":"Operator set the value in a config block as a number or with a wrong unit, generated metadata omitted the field, or tooling wrote a different casing of the key so the field reads empty.","solutions":["Set LeaderHeartbeatTimeout to a valid duration string, e.g. \"10s\"","Regenerate the config block from validated BFT options and retry channel update","Run `inspect` against the block to pre-validate metadata options","Ensure the option key is spelled exactly LeaderHeartbeatTimeout in the metadata"],"exampleFix":"// before\n\"LeaderHeartbeatTimeout\": \"\"\n// after\n\"LeaderHeartbeatTimeout\": \"10s\"","handlingStrategy":"validation","validationCode":"if _, err := time.ParseDuration(opts.LeaderHeartbeatTimeout); err != nil { return fmt.Errorf(\"LeaderHeartbeatTimeout invalid: %w\", err) }","typeGuard":null,"tryCatchPattern":"cfg, err := util.ConfigFromMetadataOptions(selfID, opts)\nif err != nil { return fmt.Errorf(\"rejecting options: %w\", err) }","preventionTips":["Set LeaderHeartbeatTimeout as a duration string with units","Don't leave the field empty in metadata templates; default to sane values","Validate blocks with inspect before commit","Keep key spelling exact when generating metadata JSON"],"tags":["hyperledger-fabric","config","smartbft","duration-parsing"],"backgroundTag":"invalid-duration-format","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"}