crowdsecurity/crowdsec · error

unable to create folder '%s': %w

Error message

unable to create folder '%s': %w

What it means

After validating the stage, installParserCustomFrom creates the stage directory under the runtime path with os.MkdirAll and wraps any failure. This is a directory-creation failure inside the test runtime tree.

Source

Thrown at pkg/hubtest/parser.go:67

	customParserPath := filepath.Join(customPath, parser)
	if _, err := os.Stat(customParserPath); os.IsNotExist(err) {
		return false, nil
	}

	customParserPathSplit, customParserName := filepath.Split(customParserPath)
	// because path is parsers/<stage>/<author>/parser.yaml and we wan't the stage
	splitPath := strings.Split(customParserPathSplit, string(os.PathSeparator))
	customParserStage := splitPath[len(splitPath)-3]

	// check if stage exist
	hubStagePath := filepath.Join(t.HubPath, fmt.Sprintf("parsers/%s", customParserStage))
	if _, err := os.Stat(hubStagePath); os.IsNotExist(err) {
		return false, fmt.Errorf("stage '%s' extracted from '%s' doesn't exist in the hub", customParserStage, hubStagePath)
	}

	stageDirDest := fmt.Sprintf("%s/parsers/%s/", t.RuntimePath, customParserStage)
	if err := os.MkdirAll(stageDirDest, os.ModePerm); err != nil {
		return false, fmt.Errorf("unable to create folder '%s': %w", stageDirDest, err)
	}

	customParserDest := filepath.Join(stageDirDest, customParserName)
	// if path to parser exist, copy it
	if err := Copy(customParserPath, customParserDest); err != nil {
		return false, fmt.Errorf("unable to copy custom parser '%s' to '%s': %w", customParserPath, customParserDest, err)
	}

	return true, nil
}

func (t *HubTestItem) installParserCustom(parser string) error {
	for _, customPath := range t.CustomItemsLocation {
		found, err := t.installParserCustomFrom(parser, customPath)
		if err != nil {
			return err
		}

View on GitHub (pinned to 909b515798)

Solutions

  1. Check permissions on the runtime path and chown/chmod it so the test user can write.
  2. Remove or rename any regular file that conflicts with the 'parsers' directory component.
  3. Verify RuntimePath in the test configuration points to a writable directory.

Example fix

// before
rt := "/var/lib/crowdsec/data" // read-only
runTests(runtimePath: rt)
// after
rt := t.TempDir() // or a writable dir
runTests(runtimePath: rt)
Defensive patterns

Strategy: validation

Validate before calling

if fi, err := os.Stat(runtimePath); err != nil || !fi.IsDir() {
	return fmt.Errorf("runtime path %s must be an existing writable directory", runtimePath)
}
if err := os.WriteFile(filepath.Join(runtimePath, ".probe"), nil, 0o644); err != nil {
	return fmt.Errorf("runtime path not writable: %w", err)
}

Try / catch

if err := item.InstallParserCustom(name); err != nil {
	if errors.Is(err, os.ErrPermission) {
		// chown/chmod runtime path and retry
	}
	return err
}

Prevention

When it happens

Trigger: os.MkdirAll(runtimePath+/parsers/<stage>/, ModePerm) failing because a parent component is a file, permission denied, or the path is invalid/too long.

Common situations: RuntimePath pointing at a read-only or non-writable location; a file named 'parsers' already existing in the runtime dir; running as unprivileged user against a root-owned runtime dir; overly long stage names on Windows.

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/1db12595256bcbeb. Report an issue: GitHub.