crowdsecurity/crowdsec · error
expected exactly one value for 'log_level'
Error message
expected exactly one value for 'log_level'
What it means
In ConfigureByDSN, the log_level query parameter must be supplied exactly once because the code needs a single log.Level value. Passing it multiple times (a slice with len != 1) is ambiguous and rejected in pkg/acquisition/modules/journalctl/config.go:105 before log.ParseLevel is attempted.
Source
Thrown at pkg/acquisition/modules/journalctl/config.go:105
}
qs := strings.TrimPrefix(dsn, "journalctl://")
if qs == "" {
return errors.New("empty journalctl:// DSN")
}
params, err := url.ParseQuery(qs)
if err != nil {
return fmt.Errorf("could not parse journalctl DSN: %w", err)
}
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)
}
}View on GitHub (pinned to 909b515798)
Solutions
- Provide log_level exactly once in the DSN: journalctl://?filters=...&log_level=info.
- Deduplicate parameters before building the DSN (keep the last/intended value).
- If multiple levels were intended, note journalctl DSNs accept a single log_level; move filtering to the filters parameter.
Example fix
// before journalctl://?filters=_SYSTEMD_UNIT=ssh&log_level=info&log_level=debug // after journalctl://?filters=_SYSTEMD_UNIT=ssh&log_level=info
Defensive patterns
Strategy: validation
Validate before calling
params := urlVals["log_level"]
if len(params) != 1 {
return fmt.Errorf("log_level must appear exactly once, got %d", len(params))
}
if _, err := log.ParseLevel(params[0]); err != nil {
return err
} 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(), "log_level") {
// rebuild DSN with a single log_level value
}
} Prevention
- Deduplicate query params before serializing the DSN.
- Treat scalar DSN params as last-wins in your config builder.
- Validate log_level against log.ParseLevel early.
When it happens
Trigger: Calling ConfigureByDSN with a DSN containing log_level more than once, e.g. journalctl://?filters=x&log_level=info&log_level=debug.
Common situations: Query builders that append a parameter per value (array semantics) when the consumer expects a scalar; accidental duplication from merging DSN strings; shell loop appending the flag repeatedly.
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 'since'
- 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/bc4add058e8eaf7d.
Report an issue: GitHub.