crowdsecurity/crowdsec · error

while creating %s: %w

Error message

while creating %s: %w

What it means

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.

Source

Thrown at pkg/hubops/enable.go:59

	}

	if i.State.IsInstalled() {
		return false, nil
	}

	return true, nil
}

// CreateInstallLink creates a symlink between the actual config file at hub.HubDir and hub.ConfigDir.
func CreateInstallLink(i *cwhub.Item) error {
	dest, err := i.PathForInstall()
	if err != nil {
		return err
	}

	destDir := filepath.Dir(dest)
	if err = os.MkdirAll(destDir, os.ModePerm); err != nil {
		return fmt.Errorf("while creating %s: %w", destDir, err)
	}

	if _, err = os.Lstat(dest); err == nil {
		// already exists
		return nil
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("failed to stat %s: %w", dest, err)
	}

	src := i.State.DownloadPath

	if err = os.Symlink(src, dest); err != nil {
		return fmt.Errorf("while creating symlink from %s to %s: %w", src, dest, err)
	}

	i.State.LocalPath = dest

	return nil

View on GitHub (pinned to 909b515798)

Solutions

  1. Create the directory manually with correct ownership: `mkdir -p <destDir> && chown crowdsec:crowdsec <destDir>`.
  2. Re-run the enable command as root or with sudo.
  3. Check that no regular file exists at any component of destDir; rename/remove it.
  4. If the filesystem is read-only, remount rw or adjust the install directory in config.

Example fix

// before
cscli parsers enable crowdsecurity/http-logs   # fails: mkdir /etc/crowdsec/parsers: permission denied
// after
sudo mkdir -p /etc/crowdsec/parsers && sudo chown crowdsec:crowdsec /etc/crowdsec/parsers
cscli parsers enable crowdsecurity/http-logs
Defensive patterns

Strategy: validation

Validate before calling

destDir := filepath.Dir(dest)
if fi, err := os.Stat(filepath.Dir(destDir)); err == nil && !fi.IsDir() {
    return fmt.Errorf("%s is a file, not a directory", filepath.Dir(destDir))
}
if err := unix.Access(destDir, unix.W_OK); err != nil {
    return fmt.Errorf("install dir %s not writable: %w", destDir, err)
}

Try / catch

if err := run(); err != nil {
    if strings.Contains(err.Error(), "while creating") {
        // mkdir failed: fix ownership or run with sudo
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/c69435a9016af663. Report an issue: GitHub.