crowdsecurity/crowdsec · error

unable to copy '%s' to '%s': %w

Error message

unable to copy '%s' to '%s': %w

What it means

installAppsecRuleItem copies the appsec-rule file from the hub source into the test runtime hub directory (Copy) and wraps any copy failure. The copy failing means the source file couldn't be read or the destination file couldn't be created/written.

Source

Thrown at pkg/hubtest/appsecrule.go:35

		return fmt.Errorf("can't get absolute path of '%s': %w", sourcePath, err)
	}

	sourceFilename := filepath.Base(sourcePath)

	// runtime/hub/appsec-rules/author/appsec-rule
	hubDirAppsecRuleDest := filepath.Join(t.RuntimeHubPath, filepath.Dir(item.RemotePath))

	// runtime/appsec-rules/
	itemTypeDirDest := fmt.Sprintf("%s/appsec-rules/", t.RuntimePath)

	if err := createDirs([]string{hubDirAppsecRuleDest, itemTypeDirDest}); err != nil {
		return err
	}

	// runtime/hub/appsec-rules/crowdsecurity/rule.yaml
	hubDirAppsecRulePath := filepath.Join(itemTypeDirDest, sourceFilename)
	if err := Copy(sourcePath, hubDirAppsecRulePath); err != nil {
		return fmt.Errorf("unable to copy '%s' to '%s': %w", sourcePath, hubDirAppsecRulePath, err)
	}

	// runtime/appsec-rules/rule.yaml
	appsecRulePath := filepath.Join(itemTypeDirDest, sourceFilename)
	if err := os.Symlink(hubDirAppsecRulePath, appsecRulePath); err != nil {
		if !os.IsExist(err) {
			return fmt.Errorf("unable to symlink appsec-rule '%s' to '%s': %w", hubDirAppsecRulePath, appsecRulePath, err)
		}
	}

	return nil
}

func (t *HubTestItem) installAppsecRuleCustomFrom(appsecrule string, customPath string) (bool, error) {
	// we check if its a custom appsec-rule
	customAppsecRulePath := filepath.Join(customPath, appsecrule)
	if _, err := os.Stat(customAppsecRulePath); os.IsNotExist(err) {
		return false, nil

View on GitHub (pinned to 909b515798)

Solutions

  1. Check the source file exists at HubPath + item.RemotePath and is readable; refresh the hub if not ('cscli hub update')
  2. Verify permissions on the runtime hub destination directory and create it manually if needed
  3. Check free disk space and that the destination filesystem is writable

Example fix

// before
t := HubTestItem{HubPath: "/old/hub", RuntimeHubPath: "/tmp/rt/hub"}
// after
t := HubTestItem{HubPath: "/etc/crowdsec/hub", RuntimeHubPath: "/tmp/rt/hub"} // source rule present
Defensive patterns

Strategy: validation

Validate before calling

src := filepath.Join(t.HubPath, item.RemotePath)
if _, err := os.Stat(src); err != nil {
	return fmt.Errorf("source appsec-rule missing: %s", src)
}
if err := os.MkdirAll(t.RuntimeHubPath, 0o755); err != nil {
	return err
}

Try / catch

if err := t.installAppsecRule(name); err != nil {
	if strings.Contains(err.Error(), "unable to copy") {
		// check source readability / destination writability before retry
	}
	return err
}

Prevention

When it happens

Trigger: installAppsecRule on a hub item where the source HubPath/RemotePath file is missing or unreadable, or the destination hubDirAppsecRulePath under RuntimeHubPath is unwritable/inexistent despite createDirs.

Common situations: Incomplete or pruned hub checkout (source rule file absent); runtime directory owned by another user; disk full; test runtime path pointing at a read-only mount.

Related errors


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