jaegertracing/jaeger · error
ttl must be a non-negative duration
Error message
ttl must be a non-negative duration
What it means
ClickHouse Configuration.Validate returns this error when the TTL field is negative. TTL controls data retention and must be a non-negative duration; a negative value is meaningless for ClickHouse table settings.
Source
Thrown at internal/storage/v2/clickhouse/config.go:83
// DefaultConfiguration returns the configuration a ClickHouse backend starts from
// before the user's own settings are unmarshaled over it.
func DefaultConfiguration() Configuration {
return Configuration{
Protocol: defaultProtocol,
Database: defaultDatabase,
DefaultSearchDepth: defaultSearchDepth,
MaxSearchDepth: defaultMaxSearchDepth,
AttributeMetadataCacheTTL: defaultAttributeMetadataCacheTTL,
AttributeMetadataCacheMaxSize: defaultAttributeMetadataCacheMaxSize,
}
}
func (cfg *Configuration) Validate() error {
if _, err := govalidator.ValidateStruct(cfg); err != nil {
return err
}
if cfg.TTL < 0 {
return errors.New("ttl must be a non-negative duration")
}
if cfg.TTL > 0 && cfg.TTL%time.Second != 0 {
return errors.New("ttl must be a whole number of seconds")
}
// A search depth of zero would make every trace search return nothing, and a
// negative one is meaningless, so reject both rather than querying with them.
if cfg.DefaultSearchDepth <= 0 {
return errors.New("default_search_depth must be a positive number")
}
if cfg.MaxSearchDepth <= 0 {
return errors.New("max_search_depth must be a positive number")
}
if cfg.AttributeMetadataCacheTTL < 0 {
return errors.New("attribute_metadata_cache_ttl must be a non-negative duration")
}
if cfg.AttributeMetadataCacheMaxSize < 0 {
return errors.New("attribute_metadata_cache_max_size must be a non-negative number")
}View on GitHub (pinned to 806f444784)
Solutions
- Set TTL to a non-negative duration (e.g. "720h" or 0 to disable expiry)
- Fix the source of the value (env var, YAML, CLI flag) so it cannot be negative
- Ensure govalidator tags plus this Validate check are run before the writer/reader are created
Example fix
// before ttl: -1h // after ttl: 720h0m0s
Defensive patterns
Strategy: validation
Validate before calling
if cfg.TTL < 0 {
return errors.New("ttl must be a non-negative duration")
} Type guard
func validTTL(d time.Duration) bool { return d >= 0 } Try / catch
if err := cfg.Validate(); err != nil {
if strings.Contains(err.Error(), "ttl must be a non-negative duration") {
cfg.TTL = defaultTTL // or fail startup with a clear message
}
} Prevention
- Validate configuration before starting the storage factory
- Never hand-write negative durations in config files
- Bind config through typed duration parsing that rejects negatives
When it happens
Trigger: Loading a ClickHouse storage configuration whose TTL is set below zero, then calling Validate (directly or via factory creation).
Common situations: Hand-edited config files with negative durations; misparsing duration strings from env/flags into negative numbers; copy-paste of a value with a stray minus sign.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- ttl must be a whole number of seconds
- default_search_depth must be a positive number
- max_search_depth must be a positive number
- attribute_metadata_cache_ttl must be a non-negative duration
- attribute_metadata_cache_max_size must be a non-negative num
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/08990ce69303847b.
Report an issue: GitHub.