hyperledger/fabric · critical
failed to parse TickInterval (%s) to time duration
Error message
failed to parse TickInterval (%s) to time duration
What it means
HandleChain (orderer/consensus/etcdraft/consenter.go:167) parses the TickInterval string from the channel's etcdraft Options into a time.Duration when no TickIntervalOverride is set in the orderer's local config. If the string is not a valid Go duration (e.g. '500' without unit), this error is returned and the chain cannot start. The value originates from channel consensus metadata, so bad metadata breaks all orderers on that channel.
Source
Thrown at orderer/consensus/etcdraft/consenter.go:167
return nil, errors.Wrap(err, "without a system channel, a follower should have been created")
}
var evictionSuspicion time.Duration
if c.EtcdRaftConfig.EvictionSuspicion == "" {
c.Logger.Infof("EvictionSuspicion not set, defaulting to %v", DefaultEvictionSuspicion)
evictionSuspicion = DefaultEvictionSuspicion
} else {
evictionSuspicion, err = time.ParseDuration(c.EtcdRaftConfig.EvictionSuspicion)
if err != nil {
c.Logger.Panicf("Failed parsing Consensus.EvictionSuspicion: %s: %v", c.EtcdRaftConfig.EvictionSuspicion, err)
}
}
var tickInterval time.Duration
if c.EtcdRaftConfig.TickIntervalOverride == "" {
tickInterval, err = time.ParseDuration(m.GetOptions().GetTickInterval())
if err != nil {
return nil, errors.Errorf("failed to parse TickInterval (%s) to time duration", m.GetOptions().GetTickInterval())
}
} else {
tickInterval, err = time.ParseDuration(c.EtcdRaftConfig.TickIntervalOverride)
if err != nil {
return nil, errors.WithMessage(err, "failed parsing Consensus.TickIntervalOverride")
}
c.Logger.Infof("TickIntervalOverride is set, overriding channel configuration tick interval to %v", tickInterval)
}
opts := Options{
RPCTimeout: c.OrdererConfig.General.Cluster.RPCTimeout,
RaftID: id,
Clock: clock.NewClock(),
MemoryStorage: raft.NewMemoryStorage(),
Logger: c.Logger,
TickInterval: tickInterval,
ElectionTick: int(m.GetOptions().GetElectionTick()),View on GitHub (pinned to 2736b63f8f)
Solutions
- Fix Options.TickInterval in the channel config to a valid duration string like "500ms" and resubmit via config update (or regenerate genesis)
- Alternatively set Orderer.EtcdRaftConfig.TickIntervalOverride (e.g. General.Consensus etcdraft TickInterval in orderer.yaml) to a valid duration to bypass the metadata value
- Validate with Go semantics: number plus unit (ns, us, ms, s, m, h) is required
Example fix
// before (channel config metadata)
Options: {TickInterval: "500"}
// after
Options: {TickInterval: "500ms"} // or in orderer.yaml: TickIntervalOverride: 500ms Defensive patterns
Strategy: validation
Validate before calling
if _, err := time.ParseDuration(raftOptions.GetTickInterval()); err != nil {
return fmt.Errorf("TickInterval %q is not a valid Go duration (e.g. \"500ms\"): %w", raftOptions.GetTickInterval(), err)
} Type guard
func tickIntervalValid(s string) bool {
_, err := time.ParseDuration(s)
return s != "" && err == nil
} Try / catch
chain, err := consenter.HandleChain(support, metadata)
if err != nil {
if strings.Contains(err.Error(), "failed to parse TickInterval") {
// fix Options.TickInterval in channel config or set TickIntervalOverride in orderer.yaml
}
} Prevention
- Always include a time unit in TickInterval (e.g. "500ms")
- Validate raft Options durations with time.ParseDuration in CI before submitting config
- Use TickIntervalOverride in orderer.yaml to decouple from channel metadata values
When it happens
Trigger: Channel consensus metadata Options.TickInterval is a string that time.ParseDuration cannot parse (missing time unit, empty string, or non-numeric), while EtcdRaftConfig.TickIntervalOverride is unset.
Common situations: Writing TickInterval: "500" or "500ms abc" in the raft Options of a custom config; hand-editing metadata and dropping the 'ms'/'s' suffix; empty TickInterval in a migrated config.
Understand the failure class
Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- etcdraft options have not been provided
- failed to parse TickInterval (%s) to time duration: %s
- chaincode type not supported: %s
- failed to copy metadataDir directory folder: %s
- error unmarshalling YAML file %s: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/6b44a458f97ae719.
Report an issue: GitHub.