{"record":{"id":"dcc6417abcde5a23","repo":"hyperledger/fabric","slug":"bad-config-metadata-option-viewchangetimeout","errorCode":null,"errorMessage":"bad config metadata option ViewChangeTimeout","messagePattern":"bad config metadata option ViewChangeTimeout","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/util/util.go","lineNumber":47,"sourceCode":"\tif config.RequestBatchMaxInterval, err = time.ParseDuration(options.RequestBatchMaxInterval); err != nil {\n\t\treturn config, errors.Wrap(err, \"bad config metadata option RequestBatchMaxInterval\")\n\t}\n\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}","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/util/util.go#L29-L65","documentation":"ConfigFromMetadataOptions parses ViewChangeTimeout from the BFT consensus metadata options via time.ParseDuration and wraps any failure with this message. An invalid ViewChangeTimeout means the view-change timing in the metadata cannot be turned into a time.Duration, so the config block is rejected and the BFT chain cannot be created or updated.","triggerScenarios":"Orderer start, channel config commit (configBlockToBFTConfig), or `inspect` when options.ViewChangeTimeout is empty or malformed (e.g. missing unit like '500', '5m30' with typo).","commonSituations":"Mistyped duration when customizing timeouts, config produced by a script that serializes milliseconds as an integer, or partially migrated metadata from an older Fabric version.","solutions":["Set ViewChangeTimeout to a valid duration string such as \"20s\" in the consensus metadata","Regenerate the channel config block with correct options and recommit it","Use `inspect` on the config block to validate all BFT metadata options before committing","Check for typos/missing time units; Go durations require units (ns/us/ms/s/m/h)"],"exampleFix":"// before\n\"ViewChangeTimeout\": \"20\"\n// after\n\"ViewChangeTimeout\": \"20s\"","handlingStrategy":"validation","validationCode":"if _, err := time.ParseDuration(opts.ViewChangeTimeout); err != nil { return fmt.Errorf(\"ViewChangeTimeout invalid: %w\", err) }","typeGuard":null,"tryCatchPattern":"cfg, err := util.ConfigFromMetadataOptions(selfID, opts)\nif err != nil { return fmt.Errorf(\"rejecting options: %w\", err) }","preventionTips":["Always include time units in ViewChangeTimeout (e.g. \"20s\")","Pre-validate options in CI with the inspect tool before channel updates","Keep BFT options in one reviewed config file to avoid partial edits","Document timeout hierarchy when customizing"],"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"}