{"record":{"id":"560f8152e7e89d27","repo":"hyperledger/fabric","slug":"bad-config-metadata-option-viewchangeresendinterva","errorCode":null,"errorMessage":"bad config metadata option ViewChangeResendInterval","messagePattern":"bad config metadata option ViewChangeResendInterval","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/util/util.go","lineNumber":44,"sourceCode":"\n\tconfig.RequestBatchMaxCount = options.RequestBatchMaxCount\n\tconfig.RequestBatchMaxBytes = options.RequestBatchMaxBytes\n\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 {","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/util/util.go#L26-L62","documentation":"ConfigFromMetadataOptions parses duration strings from the BFT consensus metadata options embedded in the orderer config block. This error wraps a time.ParseDuration failure for the ViewChangeResendInterval option, meaning the value in the block's consensus metadata is not a valid Go duration string (e.g. '10s', '1m'). The block is rejected so the chain never starts or applies invalid timing configuration.","triggerScenarios":"Orderer start (HandleChain), channel creation/update processing (configBlockToBFTConfig), or the `inspect` CLI run when the consensus metadata option ViewChangeResendInterval is missing, empty, or not a valid duration (e.g. '10', 'ten-seconds', '10sec').","commonSituations":"Hand-edited or generated config block where the option was written as a bare number of seconds, YAML value not quoted properly, empty string from a templating tool, or metadata produced by an older/newer tooling version that renamed or dropped the field.","solutions":["Fix ViewChangeResendInterval in the channel's consensus metadata options to a valid Go duration string, e.g. \"10s\"","Regenerate the config block from a correct config.yaml so the option is populated","Run the `orderer genesis inspect` tool on the offending block to confirm which option fails parsing","Verify channel config update tooling (configtxgen / configtxlator) emits duration strings, not integers"],"exampleFix":"// before (consensus metadata)\n\"ViewChangeResendInterval\": 10\n// after\n\"ViewChangeResendInterval\": \"10s\"","handlingStrategy":"validation","validationCode":"func validDuration(s string) error { _, err := time.ParseDuration(s); return err }\nif err := validDuration(opts.ViewChangeResendInterval); err != nil { return fmt.Errorf(\"ViewChangeResendInterval invalid: %w\", err) }","typeGuard":null,"tryCatchPattern":"cfg, err := util.ConfigFromMetadataOptions(selfID, opts)\nif err != nil { return fmt.Errorf(\"aborting chain start, BFT options invalid: %w\", err) }","preventionTips":["Validate all BFT option durations with time.ParseDuration before generating a config block","Quote duration values in config templates so numbers stay strings","Run `inspect` on generated blocks before committing channel updates","Pin configtxgen/tooling versions to the network's Fabric version"],"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-08T05:18:18.240Z"}