{"record":{"id":"af9c9b6c298d20f3","repo":"crowdsecurity/crowdsec","slug":"while-checking-acquisition-path-w","errorCode":null,"errorMessage":"while checking acquisition_path: %w","messagePattern":"while checking acquisition_path: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csconfig/crowdsec_service.go","lineNumber":63,"sourceCode":"func (c *CrowdsecServiceCfg) CollectAcquisitionFiles() ([]string, error) {\n\tret := []string{}\n\n\t// agent section missing in the configuration file.\n\t// likely a lapi-only setup, not much we can do here\n\tif c == nil {\n\t\treturn nil, nil\n\t}\n\n\tif c.AcquisitionFilePath != \"\" {\n\t\tlog.Debugf(\"non-empty acquisition_path %s\", c.AcquisitionFilePath)\n\n\t\t_, err := os.Stat(c.AcquisitionFilePath)\n\n\t\tswitch {\n\t\tcase errors.Is(err, fs.ErrNotExist):\n\t\t\tlog.Debugf(\"acquisition_path: %s does not exist, skipping\", c.AcquisitionFilePath)\n\t\tcase err != nil:\n\t\t\treturn nil, fmt.Errorf(\"while checking acquisition_path: %w\", err)\n\t\tdefault:\n\t\t\tret = append(ret, c.AcquisitionFilePath)\n\t\t}\n\t}\n\n\t// XXX: TODO: set default AcquisitionDirPath\n\n\tif c.AcquisitionDirPath != \"\" {\n\t\tdirFiles, err := filepath.Glob(c.AcquisitionDirPath + \"/*.yaml\")\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"while globbing acquis_dir: %w\", err)\n\t\t}\n\n\t\tret = append(ret, dirFiles...)\n\n\t\tdirFiles, err = filepath.Glob(c.AcquisitionDirPath + \"/*.yml\")\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"while globbing acquis_dir: %w\", err)","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csconfig/crowdsec_service.go#L45-L81","documentation":"CollectAcquisitionFiles stats the configured acquisition_path. A missing file is tolerated (skipped with a debug log), but any other os.Stat error — permission denied on a parent directory, path too long, I/O error — aborts with this wrapped error.","triggerScenarios":"crowdsec agent startup (LoadCrowdsec) with acquisitons.acquisition_path set and os.Stat failing with something other than ErrNotExist — typically a permission-denied traversal of a parent directory.","commonSituations":"acquisition_path under a directory the crowdsec user cannot traverse (e.g. /root/...); restrictive ACLs; mount point offline; path component is a file, not a directory.","solutions":["Fix permissions on every path component so the crowdsec user can stat the file (`chmod a+rx` on parent dirs)","Check each path component exists and is a directory (`namei -l <path>`)","Point acquisition_path to the standard /etc/crowdsec/acquis.yaml","Check dmesg/audit logs if the filesystem is degraded"],"exampleFix":"// before (config.yaml)\ncrowdsec_service:\n  acquisition_path: /root/acquis.yaml  # not traversable by crowdsec user\n// after\ncrowdsec_service:\n  acquisition_path: /etc/crowdsec/acquis.yaml","handlingStrategy":"validation","validationCode":"if acquisPath != \"\" {\n\tif _, err := os.Stat(acquisPath); err != nil && !errors.Is(err, fs.ErrNotExist) {\n\t\tlog.Fatalf(\"acquisition_path %s not statable: %v\", acquisPath, err)\n\t}\n}","typeGuard":null,"tryCatchPattern":"files, err := svcCfg.CollectAcquisitionFiles()\nif err != nil {\n\tif strings.Contains(err.Error(), \"while checking acquisition_path\") {\n\t\tlog.Fatalf(\"fix acquisition_path permissions: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Keep acquis.yaml under /etc/crowdsec, world-traversable directories","Verify with `sudo -u crowdsec stat /etc/crowdsec/acquis.yaml` after permission changes","Avoid placing acquisition files under home directories of other users"],"tags":["acquisition","filesystem","permissions","agent"],"backgroundTag":"file-read-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}