crowdsecurity/crowdsec · error

reading console config file '%s': %w

Error message

reading console config file '%s': %w

What it means

LoadConsoleConfig reads the console config file after confirming it exists; the existence check tolerates a missing file, but any other os.ReadFile failure — permission denied, path is a directory, I/O error — is wrapped with this prefix.

Source

Thrown at pkg/csconfig/console.go:80

	return ret
}

func (c *LocalApiServerCfg) LoadConsoleConfig() error {
	c.ConsoleConfig = &ConsoleConfig{}
	if _, err := os.Stat(c.ConsoleConfigPath); err != nil && os.IsNotExist(err) {
		log.Debugf("no console configuration to load")

		c.ConsoleConfig.ShareCustomScenarios = new(true)
		c.ConsoleConfig.ShareTaintedScenarios = new(true)
		c.ConsoleConfig.ShareManualDecisions = new(false)
		c.ConsoleConfig.ShareContext = new(false)

		return nil
	}

	yamlFile, err := os.ReadFile(c.ConsoleConfigPath)
	if err != nil {
		return fmt.Errorf("reading console config file '%s': %w", c.ConsoleConfigPath, err)
	}

	err = yaml.Unmarshal(yamlFile, c.ConsoleConfig)
	if err != nil {
		return fmt.Errorf("parsing console config file '%s': %w", c.ConsoleConfigPath, err)
	}

	if c.ConsoleConfig.ShareCustomScenarios == nil {
		log.Debugf("no share_custom scenarios found, setting to true")
		c.ConsoleConfig.ShareCustomScenarios = new(true)
	}

	if c.ConsoleConfig.ShareTaintedScenarios == nil {
		log.Debugf("no share_tainted scenarios found, setting to true")
		c.ConsoleConfig.ShareTaintedScenarios = new(true)
	}

	if c.ConsoleConfig.ShareManualDecisions == nil {

View on GitHub (pinned to 909b515798)

Solutions

  1. Fix file permissions so the crowdsec user can read it (`chmod/chown`)
  2. Check it's a regular file, not a directory (`file /etc/crowdsec/console.yaml`)
  3. Check audit logs for SELinux/AppArmor denials
  4. Delete the file if unneeded — absence falls back to defaults

Example fix

// before
-rw------- root root /etc/crowdsec/console.yaml
// after
sudo chown crowdsec:crowdsec /etc/crowdsec/console.yaml
sudo chmod 640 /etc/crowdsec/console.yaml
Defensive patterns

Strategy: try-catch

Validate before calling

if fi, err := os.Stat(consolePath); err == nil && fi.IsDir() { log.Fatalf("console_config_path is a directory: %s", consolePath) }

Try / catch

if err := serverCfg.LoadConsoleConfig(); err != nil {
	var pe *os.PathError
	if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {
		log.Warnf("console.yaml unreadable, using defaults: %v", pe)
		return nil
	}
	return err
}

Prevention

When it happens

Trigger: crowdsec startup where config/console.yaml (or api.server.console_config_path) exists per os.Stat but cannot be read: permission denied, it's a directory, or a filesystem error.

Common situations: File owned by root with 0600 while the service runs as crowdsec; console_config_path accidentally pointing to a directory; NFS/disk errors; SELinux denial blocking read.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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