crowdsecurity/crowdsec · error
empty journalctl:// DSN
Error message
empty journalctl:// DSN
What it means
ConfigureByDSN accepts DSNs of the form journalctl://<query-string>. After stripping the prefix, an empty remainder means there are no parameters at all — in particular no filters — so the source would be unusable and the call fails in pkg/acquisition/modules/journalctl/config.go:91.
Source
Thrown at pkg/acquisition/modules/journalctl/config.go:91
s.metricsLevel = metricsLevel
return nil
}
func (s *Source) ConfigureByDSN(_ context.Context, dsn string, labels map[string]string, logger *log.Entry, uuid string) error {
var (
filters []string
since string
logLevel log.Level
)
// format for the DSN is : journalctl://filters=FILTER1&filters=FILTER2
if !strings.HasPrefix(dsn, "journalctl://") {
return fmt.Errorf("invalid DSN %s for journalctl source, must start with journalctl://", dsn)
}
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 {View on GitHub (pinned to 909b515798)
Solutions
- Append query parameters, at minimum filters: journalctl://?filters=_SYSTEMD_UNIT=ssh.service.
- If configuring via YAML instead, use an acquis.yaml entry with journal_filter rather than a bare DSN.
- Debug DSN generation code to ensure the query string is not dropped or truncated.
Example fix
// before crowdsec -type syslog -dsn 'journalctl://' // after crowdsec -type syslog -dsn 'journalctl://?filters=_SYSTEMD_UNIT=ssh.service&log_level=info'
Defensive patterns
Strategy: validation
Validate before calling
qs := strings.TrimPrefix(dsn, "journalctl://")
if qs == "" {
return errors.New("journalctl DSN needs at least a filters parameter")
} Type guard
func validJournalctlDSN(dsn string) bool {
q, ok := strings.CutPrefix(dsn, "journalctl://")
return ok && q != ""
} Try / catch
if err := src.ConfigureByDSN(ctx, dsn); err != nil {
if strings.Contains(err.Error(), "empty journalctl:// DSN") {
// append ?filters=... and retry
}
} Prevention
- Build DSNs with url.Values encoding rather than string concatenation.
- Assert non-empty query string in code that generates DSNs.
- Prefer YAML acquisition config over bare DSNs for complex setups.
When it happens
Trigger: Calling ConfigureByDSN(ctx, "journalctl://") with no query string, or building the DSN from variables that are all empty.
Common situations: Template/CLI assembly that drops the query string; truncation of the DSN at the '?' by another tool; copy-paste that lost the parameters.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- journalctl_filter is required
- expected exactly one value for 'log_level'
- expected exactly one value for 'since'
- empty loki host
- failed to parse DSN %s: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/959561b035cd6820.
Report an issue: GitHub.