crowdsecurity/crowdsec · error

unsupported mode %s for docker datasource

Error message

unsupported mode %s for docker datasource

What it means

The docker datasource supports only `cat` and `tail` modes (defaulting to tail). After unmarshalling, UnmarshalConfig validates d.Config.Mode and returns `unsupported mode <mode> for docker datasource` for anything else, refusing to configure the datasource.

Source

Thrown at pkg/acquisition/modules/docker/config.go:89

	if d.Config.UseContainerLabels && (len(d.Config.ContainerName) > 0 || len(d.Config.ContainerID) > 0 || len(d.Config.ContainerIDRegexp) > 0 || len(d.Config.ContainerNameRegexp) > 0) {
		return errors.New("use_container_labels and container_name, container_id, container_id_regexp, container_name_regexp are mutually exclusive")
	}

	if d.Config.UseServiceLabels && (len(d.Config.ServiceName) > 0 || len(d.Config.ServiceID) > 0 || len(d.Config.ServiceIDRegexp) > 0 || len(d.Config.ServiceNameRegexp) > 0) {
		return errors.New("use_service_labels and service_name, service_id, service_id_regexp, service_name_regexp are mutually exclusive")
	}

	if d.Config.CheckInterval != "" && d.logger != nil {
		d.logger.Warn("check_interval is ignored: this datasource now uses events instead of polling (will be removed in a future version)")
	}

	if d.Config.Mode == "" {
		d.Config.Mode = configuration.TAIL_MODE
	}

	if d.Config.Mode != configuration.CAT_MODE && d.Config.Mode != configuration.TAIL_MODE {
		return fmt.Errorf("unsupported mode %s for docker datasource", d.Config.Mode)
	}

	for _, cont := range d.Config.ContainerNameRegexp {
		compiled, err := regexp.Compile(cont)
		if err != nil {
			return fmt.Errorf("container_name_regexp: %w", err)
		}

		d.compiledContainerName = append(d.compiledContainerName, compiled)
	}

	for _, cont := range d.Config.ContainerIDRegexp {
		compiled, err := regexp.Compile(cont)
		if err != nil {
			return fmt.Errorf("container_id_regexp: %w", err)
		}

		d.compiledContainerID = append(d.compiledContainerID, compiled)

View on GitHub (pinned to 909b515798)

Solutions

  1. Set mode to `tail` (follow logs continuously) or `cat` (read once to the end)
  2. Remove the mode key entirely to get the default tail behavior
  3. Check for typos and lowercase spelling — values are compared exactly

Example fix

// before
source: docker
  mode: follow
// after
source: docker
  mode: tail
Defensive patterns

Strategy: validation

Validate before calling

mode := cfg.Mode
if mode == "" { mode = "tail" }
if mode != "cat" && mode != "tail" { return fmt.Errorf("docker mode must be cat or tail, got %q", mode) }

Try / catch

if err := ds.UnmarshalConfig(cfgYaml); err != nil {
    if strings.Contains(err.Error(), "unsupported mode") { /* default to tail or correct the yaml */ }
    return err
}

Prevention

When it happens

Trigger: Acquisition YAML sets `mode: follow`, `mode: read`, or any string other than cat/tail in a docker datasource block.

Common situations: Copying `mode:` from datasources with richer mode sets (e.g. journald/kafka variants); typo like `mode: tial`; misunderstanding that empty mode means tail.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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