{"record":{"id":"3559d24befdae256","repo":"hyperledger/fabric","slug":"failed-to-parse-tickinterval-s-to-time-duration-3559d2","errorCode":null,"errorMessage":"failed to parse TickInterval (%s) to time duration: %s","messagePattern":"failed to parse TickInterval \\((.+?)\\) to time duration: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/etcdraft/util.go","lineNumber":232,"sourceCode":"\t\treturn errors.Errorf(\"nil Raft config metadata options\")\n\t}\n\n\tif metadata.GetOptions().GetHeartbeatTick() == 0 ||\n\t\tmetadata.GetOptions().GetElectionTick() == 0 ||\n\t\tmetadata.GetOptions().GetMaxInflightBlocks() == 0 {\n\t\t// if SnapshotIntervalSize is zero, DefaultSnapshotIntervalSize is used\n\t\treturn errors.Errorf(\"none of HeartbeatTick (%d), ElectionTick (%d) and MaxInflightBlocks (%d) can be zero\",\n\t\t\tmetadata.GetOptions().GetHeartbeatTick(), metadata.GetOptions().GetElectionTick(), metadata.GetOptions().GetMaxInflightBlocks())\n\t}\n\n\t// check Raft options\n\tif metadata.GetOptions().GetElectionTick() <= metadata.GetOptions().GetHeartbeatTick() {\n\t\treturn errors.Errorf(\"ElectionTick (%d) must be greater than HeartbeatTick (%d)\",\n\t\t\tmetadata.GetOptions().GetElectionTick(), metadata.GetOptions().GetHeartbeatTick())\n\t}\n\n\tif d, err := time.ParseDuration(metadata.GetOptions().GetTickInterval()); err != nil {\n\t\treturn errors.Errorf(\"failed to parse TickInterval (%s) to time duration: %s\", metadata.GetOptions().GetTickInterval(), err)\n\t} else if d == 0 {\n\t\treturn errors.Errorf(\"TickInterval cannot be zero\")\n\t}\n\n\tif len(metadata.GetConsenters()) == 0 {\n\t\treturn errors.Errorf(\"empty consenter set\")\n\t}\n\n\t// verifying certificates for being signed by CA, expiration is ignored\n\tfor _, consenter := range metadata.GetConsenters() {\n\t\tif consenter == nil {\n\t\t\treturn errors.Errorf(\"metadata has nil consenter\")\n\t\t}\n\t\tif err := validateConsenterTLSCerts(consenter, verifyOpts, true); err != nil {\n\t\t\treturn errors.WithMessagef(err, \"consenter %s:%d has invalid certificate\", consenter.GetHost(), consenter.GetPort())\n\t\t}\n\t}\n","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/util.go#L214-L250","documentation":"VerifyConfigMetadata guard: the Options.TickInterval string from the etcdraft ConfigMetadata failed time.ParseDuration. The consensus metadata carries a malformed interval (wrong format or non-numeric), and both the raw string and the parse error are reported.","triggerScenarios":"TickInterval set to an empty string, a bare number like \"500\", or a malformed string like \"0.5sec\" in the channel's Raft options.","commonSituations":"configtx.yaml TickInterval edited with an unsupported unit; locale/typo issues (e.g. \"500ms \" with trailing space); tooling writing defaults that leave TickInterval empty.","solutions":["Set TickInterval to a valid duration string, e.g. \"500ms\" (Fabric default).","Test the value locally: time.ParseDuration(v) must succeed and be non-zero.","Re-run configtxgen with corrected profile and regenerate the config update."],"exampleFix":"// before\nTickInterval: \"500\"\n// after\nTickInterval: \"500ms\"","handlingStrategy":"validation","validationCode":"if _, err := time.ParseDuration(metadata.GetOptions().GetTickInterval()); err != nil {\n\treturn fmt.Errorf(\"TickInterval %q is not a valid duration: %v\", metadata.GetOptions().GetTickInterval(), err)\n}","typeGuard":null,"tryCatchPattern":"if err := VerifyConfigMetadata(meta, opts); err != nil {\n\tif strings.Contains(err.Error(), \"failed to parse TickInterval\") {\n\t\treturn fmt.Errorf(\"set TickInterval like '500ms' in channel config: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Quote TickInterval in YAML and include the unit (\"500ms\", not 500).","Call time.ParseDuration on the value in config tooling before submission.","Stick to the Fabric default TickInterval of 500ms."],"tags":["hyperledger-fabric","raft","config","duration-parse"],"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"}