crowdsecurity/crowdsec · error

stage '%s' from extracted '%s' doesn't exist in the hub

Error message

stage '%s' from extracted '%s' doesn't exist in the hub

What it means

installPostoverflowCustomFrom installs a custom (non-hub) postoverflow extracted from an archive. The stage is derived from the archive path (postoverflows/<stage>/<author>/file.yaml). Before copying, it verifies the stage directory exists in the reference hub; if not, it refuses with this error, since the stage is not recognized.

Source

Thrown at pkg/hubtest/postoverflow.go:62

	return nil
}

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

	customPostOverflowPathSplit := strings.Split(customPostOverflowPath, "/")
	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 {

View on GitHub (pinned to 909b515798)

Solutions

  1. Verify the archive extracts to postoverflows/<stage>/<author>/file.yaml with a stage that exists in the hub
  2. Run `cscli hub update` to make sure all hub stages are present locally
  3. Fix the stage directory name in the archive to match an existing hub stage (e.g. s00-enrich)
  4. Check that t.HubPath points at the real hub root

Example fix

// before (archive layout)
postoverflows/s00-unknown/author/parse.yaml
// after
postoverflows/s00-enrich/author/parse.yaml
Defensive patterns

Strategy: validation

Validate before calling

stage := pathParts[len(pathParts)-3]
if fi, err := os.Stat(filepath.Join(hubPath, "postoverflows", stage)); err != nil || !fi.IsDir() {
    return fmt.Errorf("unknown stage %q in archive", stage)
}

Try / catch

installed, err := t.installPostoverflowCustom(archivePath)
if err != nil {
    if strings.Contains(err.Error(), "doesn't exist in the hub") {
        return fmt.Errorf("re-pack archive with a valid hub stage: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: installPostoverflowCustom called with a postoverflow archive whose extracted path has a stage component (third from the end of the path) that does not exist under HubPath/postoverflows/ — e.g. typo'd stage, wrong archive layout, or hub not downloaded.

Common situations: Testing a third-party postoverflow with a nonstandard directory structure; hub not updated so the stage folder is absent; archives built for a different hub layout version.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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