crowdsecurity/crowdsec · error
expected exactly one value for 'since'
Error message
expected exactly one value for 'since'
What it means
In ConfigureByDSN, the since query parameter must appear exactly once since it maps to a single timestamp string passed to journalctl. Duplicate occurrences yield a multi-value slice and are rejected in pkg/acquisition/modules/journalctl/config.go:116.
Source
Thrown at pkg/acquisition/modules/journalctl/config.go:116
for key, value := range params {
switch key {
case "filters":
filters = append(filters, value...)
case "log_level":
if len(value) != 1 {
return errors.New("expected exactly one value for 'log_level'")
}
lvl, err := log.ParseLevel(value[0])
if err != nil {
return err
}
logLevel = lvl
case "since":
if len(value) != 1 {
return errors.New("expected exactly one value for 'since'")
}
since = value[0]
default:
return fmt.Errorf("unsupported key %s in journalctl DSN", key)
}
}
s.config = Configuration{
DataSourceCommonCfg: configuration.DataSourceCommonCfg{
Mode: configuration.CAT_MODE,
Labels: labels,
UniqueId: uuid,
},
Filters: filters,
since: since,
}
View on GitHub (pinned to 909b515798)
Solutions
- Keep only one since value in the DSN: journalctl://?filters=...&since=2024-01-01.
- Deduplicate or let later values override earlier ones before constructing the DSN.
- Ensure any default since in your tooling is replaced, not appended, when the user provides one.
Example fix
// before journalctl://?filters=x&since=2024-01-01&since=2024-06-01 // after journalctl://?filters=x&since=2024-06-01
Defensive patterns
Strategy: validation
Validate before calling
sinceVals := urlVals["since"]
if len(sinceVals) != 1 {
return fmt.Errorf("since must appear exactly once, got %d", len(sinceVals))
} Type guard
func singleValue(vals url.Values, key string) (string, bool) {
v := vals[key]
if len(v) != 1 { return "", false }
return v[0], true
} Try / catch
if err := src.ConfigureByDSN(ctx, dsn); err != nil {
if strings.Contains(err.Error(), "since") {
// rebuild DSN keeping only one since value
}
} Prevention
- When merging default and user DSNs, replace rather than append since.
- Use a map-based query builder so repeated keys collapse.
- Test generated DSNs with url.ParseQuery and assert single values.
When it happens
Trigger: Calling ConfigureByDSN with a DSN like journalctl://?filters=x&since=2024-01-01&since=2024-06-01.
Common situations: Merging default and user-supplied DSN strings that both carry since; query-string builders using repeated-key array semantics; duplicated flags in a wrapper script.
Understand the failure class
Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.
Related errors
- expected exactly one value for 'log_level'
- empty journalctl:// DSN
- invalid DSN %s for journalctl source, must start with journa
- unsupported key %s in journalctl DSN
- query is mandatory (at least start_date and end_date or back
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/02110fb95dab6427.
Report an issue: GitHub.