crowdsecurity/crowdsec · error

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

Error message

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

What it means

After computing the destination inside the runtime hub, installParserItem copies the parser source file with Copy and wraps any copy failure. This means the parser file could not be read from the hub or written into runtime/hub/parsers/<stage>/ — a filesystem-level problem, not a config problem.

Source

Thrown at pkg/hubtest/parser.go:33

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

	sourceFilename := filepath.Base(sourcePath)

	// runtime/hub/parsers/s00-raw/crowdsecurity/
	hubDirParserDest := filepath.Join(t.RuntimeHubPath, filepath.Dir(item.RemotePath))

	// runtime/parsers/s00-raw/
	itemTypeDirDest := fmt.Sprintf("%s/parsers/%s/", t.RuntimePath, item.Stage)

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

	// runtime/hub/parsers/s00-raw/crowdsecurity/syslog-logs.yaml
	hubDirParserPath := filepath.Join(hubDirParserDest, sourceFilename)
	if err := Copy(sourcePath, hubDirParserPath); err != nil {
		return fmt.Errorf("unable to copy '%s' to '%s': %w", sourcePath, hubDirParserPath, err)
	}

	// runtime/parsers/s00-raw/syslog-logs.yaml
	parserDirParserPath := filepath.Join(itemTypeDirDest, sourceFilename)
	if err := os.Symlink(hubDirParserPath, parserDirParserPath); err != nil {
		if !os.IsExist(err) {
			return fmt.Errorf("unable to symlink parser '%s' to '%s': %w", hubDirParserPath, parserDirParserPath, err)
		}
	}

	return nil
}

func (t *HubTestItem) installParserCustomFrom(parser string, customPath string) (bool, error) {
	// we check if its a custom parser
	customParserPath := filepath.Join(customPath, parser)
	if _, err := os.Stat(customParserPath); os.IsNotExist(err) {
		return false, nil

View on GitHub (pinned to 909b515798)

Solutions

  1. Run `cscli hub update` / re-download the hub so the source parser file exists at HubPath/RemotePath.
  2. Check permissions on the runtime hub directory and ensure the test user can write it.
  3. Recreate the runtime directory (rm -rf runtime && re-run) to clear stale/partial state.
  4. Check disk space with `df -h`.

Example fix

// before
hubtest.RunTests(hubPath, runtimePath, ...)
// after
if _, err := os.Stat(filepath.Join(hubPath, "parsers")); err != nil {
	return fmt.Errorf("hub not present/corrupt at %s, run 'cscli hub update': %w", hubPath, err)
}
hubtest.RunTests(hubPath, runtimePath, ...)
Defensive patterns

Strategy: validation

Validate before calling

src := filepath.Join(hubPath, remotePath)
if _, err := os.Stat(src); err != nil {
	return fmt.Errorf("hub source file %s missing, run 'cscli hub update': %w", src, err)
}
if err := os.MkdirAll(runtimeHubPath, 0o755); err != nil {
	return err
}

Try / catch

if err := item.InstallParser(name); err != nil {
	if errors.Is(err, os.ErrPermission) {
		// fix ownership of runtime dir
	}
	return err
}

Prevention

When it happens

Trigger: Calling installParser when Copy(sourcePath, hubDirParserPath) fails: source file missing/renamed in the hub, destination directory absent (MkdirAll not reached or failed), disk full, or permission denied on the runtime directory.

Common situations: Hub not updated (`cscli hub update`) so RemotePath points to a nonexistent file; runtime dir owned by another user; read-only mount; running tests in parallel clobbering the runtime tree.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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