crowdsecurity/crowdsec · error
empty time now() - %s
Error message
empty time now() - %s
What it means
Returned by handleTimeFilters when time.Now().UTC().Add(-duration) yields the zero time value. This is a defensive check; with real clock values it is practically unreachable but signals that the computed time point is unusable for a GTE/LTE predicate.
Source
Thrown at pkg/database/alertfilter.go:54
scope = types.Ip
} else if strings.ToLower(scope) == "range" {
scope = types.Range
}
*predicates = append(*predicates, alert.SourceScopeEQ(scope))
}
func handleTimeFilters(param, value string, predicates *[]predicate.Alert) error {
// crowsdec now always sends duration without days, but we allow them for
// compatibility with other tools
duration, err := cstime.ParseDurationWithDays(value)
if err != nil {
return fmt.Errorf("while parsing duration: %w", err)
}
timePoint := time.Now().UTC().Add(-duration)
if timePoint.IsZero() {
return fmt.Errorf("empty time now() - %s", timePoint.String())
}
switch param {
case "since":
*predicates = append(*predicates, alert.StartedAtGTE(timePoint))
case "created_before":
*predicates = append(*predicates, alert.CreatedAtLTE(timePoint))
case "until":
*predicates = append(*predicates, alert.StartedAtLTE(timePoint))
}
return nil
}
func handleAlertIPv4Predicates(rng csnet.Range, contains bool, predicates *[]predicate.Alert) {
if contains { // decision contains {start_ip,end_ip}
*predicates = append(*predicates, alert.And(
alert.HasDecisionsWith(decision.StartIPLTE(rng.Start.Addr)),View on GitHub (pinned to 909b515798)
Solutions
- Verify system clock is sane (date; timedatectl) — an absurdly wrong clock is the realistic trigger.
- Remove any test/mocked clock returning zero time.Time{} and inject a realistic one.
- Update crowdsec, as newer versions may have dropped or refined this check.
Defensive patterns
Strategy: try-catch
Validate before calling
if time.Now().IsZero() {
return fmt.Errorf("system clock reports zero time; refusing to build filter")
} Try / catch
preds, err := alertPredicatesFromFilter(filter)
if err != nil {
log.Warnf("time filter rejected: %v", err)
return http.StatusBadRequest
} Prevention
- Keep system clock synchronized (NTP/chrony)
- In tests, never mock now() to return time.Time{}
- Treat this error as an environment problem, not a data problem
When it happens
Trigger: The computed timePoint from now minus the parsed duration equals time.Time{} — only possible in degenerate conditions (clock anomalies, mocked zero clocks in tests).
Common situations: Test environments with a zero-valued mocked clock, or exotic time sources returning the zero time.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- no listen_uri or listen_socket specified
- no API client section in configuration
- missing token value for api.server.auto_register
- missing allowed_ranges value for api.server.auto_register
- while parsing duration: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/8043871701adb326.
Report an issue: GitHub.