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

  1. Set TTL to a non-negative duration (e.g. "720h" or 0 to disable expiry)
  2. Fix the source of the value (env var, YAML, CLI flag) so it cannot be negative
  3. 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

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


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/08990ce69303847b. Report an issue: GitHub.