crowdsecurity/crowdsec · error
unable to copy custom parser '%s' to '%s': %w
Error message
unable to copy custom parser '%s' to '%s': %w
What it means
Finally, installPostoverflowCustomFrom copies the extracted custom postoverflow file into the stage directory of the runtime via Copy(). Failure (source unreadable, destination not writable) is wrapped with both source and destination paths. Note the message says 'custom parser' even though this is a postoverflow — a historical naming artifact.
Source
Thrown at pkg/hubtest/postoverflow.go:73
customPostoverflowName := customPostOverflowPathSplit[len(customPostOverflowPathSplit)-1]
// because path is postoverflows/<stage>/<author>/parser.yaml and we wan't the stage
customPostoverflowStage := customPostOverflowPathSplit[len(customPostOverflowPathSplit)-3]
// check if stage exist
hubStagePath := filepath.Join(t.HubPath, fmt.Sprintf("postoverflows/%s", customPostoverflowStage))
if _, err := os.Stat(hubStagePath); os.IsNotExist(err) {
return false, fmt.Errorf("stage '%s' from extracted '%s' doesn't exist in the hub", customPostoverflowStage, hubStagePath)
}
stageDirDest := fmt.Sprintf("%s/postoverflows/%s/", t.RuntimePath, customPostoverflowStage)
if err := os.MkdirAll(stageDirDest, os.ModePerm); err != nil {
return false, fmt.Errorf("unable to create folder '%s': %w", stageDirDest, err)
}
customPostoverflowDest := filepath.Join(stageDirDest, customPostoverflowName)
// if path to postoverflow exist, copy it
if err := Copy(customPostOverflowPath, customPostoverflowDest); err != nil {
return false, fmt.Errorf("unable to copy custom parser '%s' to '%s': %w", customPostOverflowPath, customPostoverflowDest, err)
}
return true, nil
}
func (t *HubTestItem) installPostoverflowCustom(postoverflow string) error {
for _, customPath := range t.CustomItemsLocation {
found, err := t.installPostoverflowCustomFrom(postoverflow, customPath)
if err != nil {
return err
}
if found {
return nil
}
}
return fmt.Errorf("couldn't find custom postoverflow '%s' in the following location: %+v", postoverflow, t.CustomItemsLocation)View on GitHub (pinned to 909b515798)
Solutions
- Read the wrapped Copy error for the exact OS cause and fix permissions/paths
- Confirm the extracted source file exists at customPostOverflowPath and is readable
- Ensure the stage directory was created (check that error 1178 did not occur earlier)
- Re-extract the archive cleanly and retry the hub test
Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := os.Stat(srcPath); err != nil {
return fmt.Errorf("extracted postoverflow missing: %w", err)
}
if f, err := os.OpenFile(srcPath, os.O_RDONLY, 0); err != nil {
return fmt.Errorf("source unreadable: %w", err)
} else { f.Close() } Try / catch
if err := t.installPostoverflowCustom(p); err != nil {
if strings.Contains(err.Error(), "unable to copy") {
log.Errorf("copy failed, check perms/space: %v", err)
}
return err
} Prevention
- Re-extract archives with sane permissions (0644 files)
- Watch free disk space in CI runners
- Fix earlier mkdir/copy failures — they cascade into this error
- On Windows, exclude test trees from antivirus file locking
When it happens
Trigger: Copy(customPostOverflowPath, customPostoverflowDest) fails: extracted source file unreadable or missing, stage directory not writable (or not created due to earlier failure), or destination path is a directory.
Common situations: Archive extraction left the file without read permissions; earlier MkdirAll failure cascaded into a copy failure; antivirus/file lock interfering on Windows; disk full in CI.
Related errors
- unable to copy '%s' to '%s': %w
- cannot copy a folder onto itself
- while find parser asserts: %w
- while reading %s: %w
- while find scenario asserts: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/8a4e6d498c20e1c4.
Report an issue: GitHub.