crowdsecurity/crowdsec · error

while opening capi whitelist file: %w

Error message

while opening capi whitelist file: %w

What it means

LoadCapiWhitelists opens the deprecated capi_whitelists_path file with os.Open before parsing. Any open failure (missing file, bad path, permissions) is wrapped with this prefix. The feature is deprecated in favor of centralized allowlists.

Source

Thrown at pkg/csconfig/api.go:499

			return nil, err
		}

		ret.Cidrs[idx] = tnet
	}

	return ret, nil
}

func (c *LocalApiServerCfg) LoadCapiWhitelists() error {
	if c.CapiWhitelistsPath == "" {
		return nil
	}

	log.Warn("capi_whitelists_path is deprecated, please use centralized allowlists instead. See https://docs.crowdsec.net/docs/next/local_api/centralized_allowlists.")

	fd, err := os.Open(c.CapiWhitelistsPath)
	if err != nil {
		return fmt.Errorf("while opening capi whitelist file: %w", err)
	}

	defer fd.Close()

	c.CapiWhitelists, err = parseCapiWhitelists(fd)
	if err != nil {
		return fmt.Errorf("while parsing capi whitelist file '%s': %w", c.CapiWhitelistsPath, err)
	}

	return nil
}

func (c *Config) LoadAPIClient() error {
	if c.API == nil || c.API.Client == nil || c.API.Client.CredentialsFilePath == "" || c.DisableAgent {
		return errors.New("no API client section in configuration")
	}

	return c.API.Client.Load()

View on GitHub (pinned to 909b515798)

Solutions

  1. Check the path in api.server.capi_whitelists_path exists (`ls -l`) and is readable
  2. Remove capi_whitelists_path and migrate to centralized allowlists (`cscli allowlist`)
  3. Fix the path typo or restore the whitelist file
  4. Verify permissions for the crowdsec service user

Example fix

// before (config.yaml)
api:
  server:
    capi_whitelists_path: /etc/crowdsec/capi_whitelists.yaml  # missing
// after
# remove the key entirely, use centralized allowlists:
# cscli allowlists create ... / cscli allowlist ...
Defensive patterns

Strategy: validation

Validate before calling

if path := cfg.API.Server.CapiWhitelistsPath; path != "" {
	if _, err := os.Stat(path); err != nil {
		log.Fatalf("capi_whitelists_path %s unusable: %v", path, err)
	}
}

Try / catch

if err := serverCfg.LoadCapiWhitelists(); err != nil {
	var pe *os.PathError
	if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrNotExist) {
		log.Warnf("whitelist file missing, skipping: %v", pe)
		return nil
	}
	return err
}

Prevention

When it happens

Trigger: config.yaml sets api.server.capi_whitelists_path to a path that does not exist or is not readable by the crowdsec process at LAPI startup.

Common situations: Stale capi_whitelists_path after moving config dirs; typo in path; file deleted by cleanup scripts; migrating setups where the whitelist file was never copied to the new host.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


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