crowdsecurity/crowdsec · error

while parsing duration: %w

Error message

while parsing duration: %w

What it means

Returned by handleTimeFilters when cstime.ParseDurationWithDays cannot parse the 'since' / 'created_*' filter value into a duration. The LAPI alert filters accept Go-style durations (optionally with days) and this error wraps the parse failure.

Source

Thrown at pkg/database/alertfilter.go:49

	}
}

func handleScopeFilter(scope string, predicates *[]predicate.Alert) {
	if strings.ToLower(scope) == "ip" {
		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
}

View on GitHub (pinned to 909b515798)

Solutions

  1. Correct the duration value to a supported format: '2h', '30m', '7d' (days allowed by cstime), e.g. ?since=24h.
  2. Use RFC3339-free duration strings; do not send timestamps in this parameter.
  3. If a client library builds the query, escape/validate the duration before sending.
  4. Check cstime.ParseDurationWithDays docs for accepted syntax (with/without days).

Example fix

// before
GET /v1/alerts?since=24
// after
GET /v1/alerts?since=24h
Defensive patterns

Strategy: validation

Validate before calling

re := regexp.MustCompile(`^\d+(ns|us|µs|ms|s|m|h|d)$`)
if !re.MatchString(value) {
    return fmt.Errorf("duration %q invalid; use e.g. 24h or 7d", value)
}

Try / catch

preds, err := alertPredicatesFromFilter(filter)
var inv *InvalidFilterError
if err != nil {
    if errors.As(err, &inv) { /* return 400 to client */ }
    return err
}

Prevention

When it happens

Trigger: A LAPI/ cscli alerts query carries a time filter param (e.g. since=...) whose value is not a valid duration string, such as since=abc or since=3 (no unit).

Common situations: Typoed duration in API queries or scripts hitting the Local API, forgetting 'h'/'d' suffix (e.g. since=24 instead of 24h), or integrations sending epoch timestamps instead of durations.

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.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/b1759ea8175c8785. Report an issue: GitHub.