{"record":{"id":"d495b8d7776d3470","repo":"crowdsecurity/crowdsec","slug":"failed-to-stat-s-w","errorCode":null,"errorMessage":"failed to stat %s: %w","messagePattern":"failed to stat (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hubops/enable.go","lineNumber":66,"sourceCode":"}\n\n// CreateInstallLink creates a symlink between the actual config file at hub.HubDir and hub.ConfigDir.\nfunc CreateInstallLink(i *cwhub.Item) error {\n\tdest, err := i.PathForInstall()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdestDir := filepath.Dir(dest)\n\tif err = os.MkdirAll(destDir, os.ModePerm); err != nil {\n\t\treturn fmt.Errorf(\"while creating %s: %w\", destDir, err)\n\t}\n\n\tif _, err = os.Lstat(dest); err == nil {\n\t\t// already exists\n\t\treturn nil\n\t} else if !os.IsNotExist(err) {\n\t\treturn fmt.Errorf(\"failed to stat %s: %w\", dest, err)\n\t}\n\n\tsrc := i.State.DownloadPath\n\n\tif err = os.Symlink(src, dest); err != nil {\n\t\treturn fmt.Errorf(\"while creating symlink from %s to %s: %w\", src, dest, err)\n\t}\n\n\ti.State.LocalPath = dest\n\n\treturn nil\n}\n\nfunc (c *EnableCommand) Run(_ context.Context, plan *ActionPlan) error {\n\ti := c.Item\n\n\tfmt.Fprintln(os.Stdout, \"enabling \" + colorizeItemName(i.FQName()))\n","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/hubops/enable.go#L48-L84","documentation":"Before symlinking, CreateInstallLink runs os.Lstat(dest); if Lstat fails with an error other than NotExist (which is the normal \"link missing\" case), the operation aborts with this error. It guards against unexpected filesystem states at the destination of the install link.","triggerScenarios":"During enable/install when Lstat on the destination path fails due to permission denied on the parent directory, a symlink loop (ELOOP), or I/O error — anything except \"file does not exist\".","commonSituations":"Parent install directory not writable/searchable by the running user; corrupt dangling symlink chains left by manual cleanup; filesystem errors on degraded storage.","solutions":["Check permissions on the destination's parent directory: `ls -ld <destDir>` and fix with chown/chmod.","Inspect the dest path for a broken symlink loop (`ls -l <dest>`, `readlink -f <dest>`).","Remove the problematic leftover entry and re-run the enable command.","Run the command as root if the install directory is root-owned."],"exampleFix":"// inspect and clear a bad destination\nls -ld /etc/crowdsec/parsers/sudo/\nsudo rm -rf /etc/crowdsec/parsers/sudo\nsudo cscli parsers enable sudo","handlingStrategy":"validation","validationCode":"if _, err := os.Lstat(dest); err != nil && !os.IsNotExist(err) {\n    return fmt.Errorf(\"destination %s in bad state: %w\", dest, err)\n}","typeGuard":null,"tryCatchPattern":"_, err := os.Lstat(dest)\nif err != nil && !errors.Is(err, fs.ErrNotExist) {\n    // resolve permissions or symlink loop before retrying enable\n}","preventionTips":["Manually remove leftover/broken entries in /etc/crowdsec/<type>s before re-enabling items.","Check parent directory search (x) permission for the running user.","Investigate symlink loops after manual copy/rsync of hub directories.","Monitor storage health on hosts where lstat fails with I/O errors."],"tags":["filesystem","lstat","permissions","symlink"],"backgroundTag":"permission-denied","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}