crowdsecurity/crowdsec · error
failed to read %s: %w
Error message
failed to read %s: %w
What it means
newLocalItem reads a local item file from disk to extract an optional 'name' field from its yaml front matter. If os.ReadFile fails (missing file, permission problem, path is a directory), the underlying OS error is wrapped in 'failed to read %s' and the item cannot be registered during hub sync.
Source
Thrown at pkg/cwhub/sync.go:197
item := &Item{
hub: h,
Name: spec.fname,
Stage: spec.stage,
Type: spec.ftype,
FileName: fileName,
State: ItemState{
LocalPath: path,
local: true,
UpToDate: true,
},
}
// try to read the name from the file
itemName := localItemName{}
itemContent, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read %s: %w", path, err)
}
err = yaml.Unmarshal(itemContent, &itemName)
if err != nil {
return nil, fmt.Errorf("failed to parse %s: %w", path, err)
}
if itemName.Name != "" {
item.Name = itemName.Name
}
return item, nil
}
// ErrSkipPath is a sentinel to skip regular files because "nil, nil" is ambiguous. Returning SkipDir with files would skip the rest of the directory.
var ErrSkipPath = errors.New("sentinel")
func (h *Hub) itemVisit(path string, f os.DirEntry, err error) (*itemSpec, error) {View on GitHub (pinned to 909b515798)
Solutions
- Check the file exists: ls -l <path>; restore it or remove stale references/symlinks
- Fix permissions so the user running crowdsec can read it (chmod/chown)
- If the path is a directory or non-regular file, move it out of the scanned config directory
Example fix
// before cscli hub item install crowdsecurity/ssh_bf -t scenarios # run as root, files 0600 root:root # crowdsec service runs as 'crowdsec' user and cannot read them // after chown -R crowdsec:crowdsec /etc/crowdsec/ chmod -R u+r /etc/crowdsec/
Defensive patterns
Strategy: try-catch
Validate before calling
import "os"
func readable(path string) error {
info, err := os.Stat(path)
if err != nil {
return err
}
if !info.Mode().IsRegular() {
return fmt.Errorf("%s is not a regular file", path)
}
f, err := os.Open(path)
if err != nil {
return err
}
return f.Close()
} Try / catch
if err := hub.Load(ctx); err != nil {
if errors.Is(err, os.ErrPermission) || errors.Is(err, os.ErrNotExist) {
log.Warnf("local item unreadable, skipping: %v", err)
return nil
}
return err
} Prevention
- Run cscli and crowdsec as the same user (or chown -R crowdsec:crowdsec /etc/crowdsec)
- Keep config file permissions at least group/others-readable for the service user
- Clean up broken symlinks after uninstalling items
When it happens
Trigger: syncDir/addItemFromSpec references a path that no longer exists (deleted between listing and reading), or is unreadable by the user running crowdsec (root-only permissions), or is a directory/special file.
Common situations: Permissions tightened on /etc/crowdsec after running cscli as root then crowdsec as another user; broken symlinks left behind after uninstalls; race with an editor that deletes and recreates config files.
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
- while checking acquisition_path: %w
- while creating directories for %s: %w
- while dumping console config to %s: %w
- while opening %s: %w
- while creating %s: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/73cee05f5a550072.
Report an issue: GitHub.