crowdsecurity/crowdsec · error

error parsing duration '%s' of %s: %w

Error message

error parsing duration '%s' of %s: %w

What it means

When a profile's decision has a static `duration` string, NewProfile validates it with cstime.ParseDurationWithDays, which extends Go's time.ParseDuration to accept units like days (e.g. '4d'). If the string cannot be parsed (bad unit, empty, malformed number), NewProfile returns this error and configuration loading fails.

Source

Thrown at pkg/csprofiles/csprofiles.go:86

			if runtimeDurationExpr, err = expr.Compile(profile.DurationExpr, exprhelpers.GetExprOptions(map[string]interface{}{"Alert": &models.Alert{}})...); err != nil {
				return nil, fmt.Errorf("error compiling duration_expr of %s: %w", profile.Name, err)
			}

			runtime.RuntimeDurationExpr = runtimeDurationExpr
		}

		for _, decision := range profile.Decisions {
			if runtime.RuntimeDurationExpr == nil {
				var duration string
				if decision.Duration != nil {
					duration = *decision.Duration
				} else {
					runtime.Logger.Warningf("No duration specified for %s, using default duration %s", profile.Name, defaultDuration)
					duration = defaultDuration
				}

				if _, err := cstime.ParseDurationWithDays(duration); err != nil {
					return nil, fmt.Errorf("error parsing duration '%s' of %s: %w", duration, profile.Name, err)
				}
			}
		}

		profilesRuntime = append(profilesRuntime, runtime)
	}

	return profilesRuntime, nil
}

func (profile *Runtime) GenerateDecisionFromProfile(alert *models.Alert) ([]*models.Decision, error) {
	var decisions []*models.Decision

	for _, refDecision := range profile.Cfg.Decisions {
		decision := models.Decision{}
		/*the reference decision from profile is in simulated mode */
		if refDecision.Simulated != nil && *refDecision.Simulated {
			decision.Simulated = new(bool)

View on GitHub (pinned to 909b515798)

Solutions

  1. Use supported units: s, m, h, d (days) — e.g. '4h', '2d'.
  2. Convert unsupported units manually (1w = 7d).
  3. Ensure the value is a non-empty quoted string in YAML to avoid type coercion surprises.
  4. If no duration is desired, rely on the profile default rather than leaving a malformed value.

Example fix

// before (profiles.yaml)
duration: 4w
// after
duration: 28d
Defensive patterns

Strategy: validation

Validate before calling

if _, err := cstime.ParseDurationWithDays(cfgDuration); err != nil {
    return fmt.Errorf("invalid profile duration %q: %w", cfgDuration, err)
}

Prevention

When it happens

Trigger: A profile decision in configuration specifies a `duration` value that ParseDurationWithDays cannot parse: e.g. `duration: "4days"`, `duration: ""` when a default isn't set, `duration: "4w"` (weeks unsupported), or missing units like `duration: "4"`.

Common situations: Typos in profiles.yaml; copying durations from other tools that use different unit conventions (w for weeks, mo for months); forgetting units entirely; YAML quoting issues turning a valid value into something else.

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/65f46eeb81480638. Report an issue: GitHub.