crowdsecurity/crowdsec · error

log_level must be a single value

Error message

log_level must be a single value

What it means

In the DSN query string, the 'log_level' parameter must appear exactly once with one value. url.ParseQuery returns values as slices, so repeated keys (log_level=a&log_level=b) are rejected as ambiguous.

Source

Thrown at pkg/acquisition/modules/wineventlog/config_windows.go:218

	}

	if len(args) > 2 {
		return errors.New("too many arguments in DSN")
	}

	s.config.EventFile = args[0]

	if len(args) == 2 && args[1] != "" {
		params, err := url.ParseQuery(args[1])
		if err != nil {
			return fmt.Errorf("failed to parse DSN parameters: %w", err)
		}

		for key, value := range params {
			switch key {
			case "log_level":
				if len(value) != 1 {
					return errors.New("log_level must be a single value")
				}
				lvl, err := log.ParseLevel(value[0])
				if err != nil {
					return fmt.Errorf("failed to parse log_level: %s", err)
				}
				s.logger.Logger.SetLevel(lvl)
			case "event_id":
				for _, id := range value {
					evtid, err := strconv.Atoi(id)
					if err != nil {
						return fmt.Errorf("failed to parse event_id: %s", err)
					}
					s.config.EventIDs = append(s.config.EventIDs, evtid)
				}
			case "event_level":
				if len(value) != 1 {
					return errors.New("event_level must be a single value")
				}

View on GitHub (pinned to 909b515798)

Solutions

  1. Keep a single log_level parameter in the DSN query string
  2. Choose one level (e.g. log_level=info) and remove duplicates
  3. Note this differs from a parse failure: if the single value is invalid you get 'failed to parse log_level' instead

Example fix

// before
wineventlog://Security?log_level=info&log_level=debug
// after
wineventlog://Security?log_level=debug
Defensive patterns

Strategy: validation

Validate before calling

// Go: deduplicate and validate log_level before building the DSN
params := url.Values{}
params.Set("log_level", "info") // Set replaces, avoiding duplicates
if _, err := log.ParseLevel(level); err != nil {
    return fmt.Errorf("invalid log_level %q: %w", level, err)
}

Try / catch

if err := src.ConfigureByDSN(dsn); err != nil {
    return fmt.Errorf("bad wineventlog DSN params: %w", err)
}

Prevention

When it happens

Trigger: ConfigureByDSN called with a DSN whose query string contains 'log_level' more than once, e.g. wineventlog://Security?log_level=info&log_level=debug.

Common situations: Template concatenation appending log_level twice; hand-editing a DSN and leaving a duplicate parameter; a loop building the query string without deduplicating keys.

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


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