crowdsecurity/crowdsec · error
while opening %s: %w
Error message
while opening %s: %w
What it means
loadConfig walks the notification config directory and opens every .yaml/.yml file with os.Open; when the OS open fails (permissions, dangling symlink, deleted mid-iteration), the path and the underlying error are wrapped as "while opening %s: %w". It means a file inside the notifications directory could not be read, not that its content is invalid (that is error in %s, 802).
Source
Thrown at pkg/csplugin/broker.go:228
}
return false
}
func (pb *PluginBroker) loadConfig(path string) error {
files, err := listFilesAtPath(path)
if err != nil {
return err
}
for _, configFilePath := range files {
if !strings.HasSuffix(configFilePath, ".yaml") && !strings.HasSuffix(configFilePath, ".yml") {
continue
}
fin, err := os.Open(configFilePath)
if err != nil {
return fmt.Errorf("while opening %s: %w", configFilePath, err)
}
pluginConfigs, err := NewPluginConfigList(fin)
if err != nil {
return fmt.Errorf("error in %s: %w", configFilePath, err)
}
for _, pluginConfig := range pluginConfigs {
if _, ok := pb.pluginConfigByName[pluginConfig.Name]; ok {
log.Warningf("notification '%s' is defined multiple times", pluginConfig.Name)
}
pb.pluginConfigByName[pluginConfig.Name] = pluginConfig
if !pb.profilesContainPlugin(pluginConfig.Name) {
continue
}
}
}View on GitHub (pinned to 909b515798)
Solutions
- Check permissions on the reported file and its parent directory: crowdsec's runtime user needs read access.
- Verify the file exists (ls -l /etc/crowdsec/notifications/); remove dangling symlinks.
- Fix ownership: chown root:crowdsec and chmod 640 on notification yaml files.
- Remove or rename non-config leftovers if the file is genuinely not meant to be a plugin config.
Example fix
// before: unreadable config -rw------- root root http.yaml // after chown root:crowdsec /etc/crowdsec/notifications/http.yaml && chmod 640 /etc/crowdsec/notifications/http.yaml
Defensive patterns
Strategy: validation
Validate before calling
for _, f := range yamlFiles(notifDir) {
fi, err := os.Stat(f)
if err != nil || !fi.Mode().IsRegular() { continue }
if h, err2 := os.Open(f); err2 != nil { log.Warnf("unreadable %s: %v", f, err2); continue } else { h.Close() }
} Try / catch
if err := broker.Init(ctx, cfg); err != nil {
if strings.Contains(err.Error(), "while opening") {
// surface file path + check perms before retry
}
return err
} Prevention
- Standardize notification config ownership/permissions (root:crowdsec, 0640).
- Avoid symlinks in the notifications directory.
- Never hand-edit configs while crowdsec is reloading them.
When it happens
Trigger: PluginBroker.Init -> loadConfig when os.Open(configFilePath) returns an error: permission denied on the file, directory listed a file that vanished, or an unreadable symlink.
Common situations: Notification configs in /etc/crowdsec/notifications owned by root with 0600 while crowdsec runs as another user; config file deleted between directory listing and open; NFS/automount hiccup.
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
- failed to open feature flags file: %w
- can't access parsing configuration file %s : %s
- while getting process attributes: both plugin user and group
- could not access CRL file: %w
- reading console config file '%s': %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/8257c441b42afa1a.
Report an issue: GitHub.