{"record":{"id":"c69435a9016af663","repo":"crowdsecurity/crowdsec","slug":"while-creating-s-w-c69435","errorCode":null,"errorMessage":"while creating %s: %w","messagePattern":"while creating (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hubops/enable.go","lineNumber":59,"sourceCode":"\t}\n\n\tif i.State.IsInstalled() {\n\t\treturn false, nil\n\t}\n\n\treturn true, nil\n}\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","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/hubops/enable.go#L41-L77","documentation":"CreateInstallLink creates the hub's install directory hierarchy (MkdirAll on filepath.Dir(dest)) before symlinking the downloaded item into place. This error wraps an os.MkdirAll failure, meaning the parent directory of the install link could not be created.","triggerScenarios":"During `cscli <type> enable`/install (CreateInstallLink, called from Run) when the install dir (e.g. /etc/crowdsec/<type>s/) cannot be created due to permissions, read-only filesystem, or a non-directory file existing at some path component.","commonSituations":"Crowdsec running as non-root while /etc/crowdsec is root-owned; /etc mounted read-only (containers, immutable infra); a file named like the target directory exists in the path.","solutions":["Create the directory manually with correct ownership: `mkdir -p <destDir> && chown crowdsec:crowdsec <destDir>`.","Re-run the enable command as root or with sudo.","Check that no regular file exists at any component of destDir; rename/remove it.","If the filesystem is read-only, remount rw or adjust the install directory in config."],"exampleFix":"// before\ncscli parsers enable crowdsecurity/http-logs   # fails: mkdir /etc/crowdsec/parsers: permission denied\n// after\nsudo mkdir -p /etc/crowdsec/parsers && sudo chown crowdsec:crowdsec /etc/crowdsec/parsers\ncscli parsers enable crowdsecurity/http-logs","handlingStrategy":"validation","validationCode":"destDir := filepath.Dir(dest)\nif fi, err := os.Stat(filepath.Dir(destDir)); err == nil && !fi.IsDir() {\n    return fmt.Errorf(\"%s is a file, not a directory\", filepath.Dir(destDir))\n}\nif err := unix.Access(destDir, unix.W_OK); err != nil {\n    return fmt.Errorf(\"install dir %s not writable: %w\", destDir, err)\n}","typeGuard":null,"tryCatchPattern":"if err := run(); err != nil {\n    if strings.Contains(err.Error(), \"while creating\") {\n        // mkdir failed: fix ownership or run with sudo\n    }\n}","preventionTips":["Pre-create /etc/crowdsec/<type>s directories with correct ownership during provisioning.","Run cscli enable/install commands as the same user that owns the config tree (or root).","Keep /etc mounted read-write on hosts where crowdsec manages its config.","Use the same volume/user settings when running crowdsec in containers."],"tags":["filesystem","mkdir","permissions","hub"],"backgroundTag":"mkdir-permission-denied","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"}