crowdsecurity/crowdsec · error

invalid DSN %s for journalctl source, must start with journa

Error message

invalid DSN %s for journalctl source, must start with journalctl://

What it means

ConfigureByDSN expects a data-source string that begins with the 'journalctl://' scheme. Any DSN passed to the journalctl source with a different or missing prefix is rejected with this error. It is a fast guard before query-string parsing is attempted.

Source

Thrown at pkg/acquisition/modules/journalctl/config.go:86

	if err := s.UnmarshalConfig(yamlConfig); err != nil {
		return err
	}

	s.setLogger(logger, 0, s.src)
	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 {

View on GitHub (pinned to 909b515798)

Solutions

  1. Prefix the DSN exactly with 'journalctl://', e.g. journalctl://filters=_SYSTEMD_UNIT=sshd.service.
  2. Verify the source type in acquis.yaml is journalctl so the DSN is routed to this ConfigureByDSN.
  3. Check for shell/CLI escaping that may have eaten characters from the DSN string.

Example fix

// before
s.ConfigureByDSN("journalctl:filters=_SYSTEMD_UNIT=sshd.service")
// after
s.ConfigureByDSN("journalctl://filters=_SYSTEMD_UNIT=sshd.service")
Defensive patterns

Strategy: validation

Validate before calling

if !strings.HasPrefix(dsn, "journalctl://") || len(dsn) <= len("journalctl://") {
    return errors.New("DSN must be journalctl://<querystring> with a non-empty query")
}

Try / catch

if err := src.ConfigureByDSN(dsn); err != nil {
    if strings.Contains(err.Error(), "invalid DSN") {
        // fix scheme prefix and retry
    }
}

Prevention

When it happens

Trigger: Calling Source.ConfigureByDSN with a DSN like 'journalctl:filters=...' (single slash), 'file://...', or a bare filter expression without the scheme prefix.

Common situations: Hand-written acquis entries missing the '://'; copy-pasting a DSN from another source type (file://, syslog://); shell quoting stripping a slash.

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


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