crowdsecurity/crowdsec · error

%s is already downloaded at %s

Error message

%s is already downloaded at %s

What it means

Item.PathForDownload computes where an item should be downloaded. If the item is already downloaded but the newly computed path differs from the recorded State.DownloadPath, the same-named item lives in two locations — an inconsistent state the library refuses to guess about, returning an error.

Source

Thrown at pkg/cwhub/item.go:145

	if i.Stage != "" {
		p = filepath.Join(p, i.Stage)
	}

	return SafePath(i.hub.local.InstallDir, filepath.Join(p, i.FileName))
}

// PathForDownload returns the path to use to store the item's file from the hub
// (eg. /etc/crowdsec/hub/collections/author/xyz.yaml).
// Raises an error if the path goes outside of the hub dir.
func (i *Item) PathForDownload() (string, error) {
	path, err := SafePath(i.hub.local.HubDir, i.RemotePath)

	if i.State.IsDownloaded() && path != i.State.DownloadPath {
		// A hub item with the same name is at a different location.
		// This should not happen.
		// user is downloading with --force so we are allowed to overwrite but
		// should we remove the old location from here? Error, warning, more tests?
		return "", fmt.Errorf("%s is already downloaded at %s", i.FQName(), i.State.DownloadPath)
	}

	return path, err
}

// HasSubItems returns true if items of this type can have sub-items. Currently only collections.
func (i *Item) HasSubItems() bool {
	return i.Type == COLLECTIONS
}

// MarshalJSON is used to prepare the output for "cscli ... inspect -o json".
// It must not use a pointer receiver.
func (i Item) MarshalJSON() ([]byte, error) {
	type Alias Item

	return json.Marshal(&struct {
		Alias
		// we have to repeat the fields here, json will have inline support in v2

View on GitHub (pinned to 909b515798)

Solutions

  1. Remove the stale file at i.State.DownloadPath (or `cscli hub remove` the item) and re-download
  2. Re-align config so install/hub dirs match where items were originally downloaded
  3. Reset hub state by re-running `cscli hub update` and reinstalling affected items
  4. If intentional, clear the item's State before calling PathForDownload

Example fix

// before
path, err := item.PathForDownload(downloadDir) // errors: different location
// after
os.Remove(item.State.DownloadPath) // clean stale copy first
path, err := item.PathForDownload(downloadDir)
Defensive patterns

Strategy: try-catch

Validate before calling

if item.State.IsDownloaded() {
    expected, _ := item.PathForDownload(dir) // may error; compare first
    _ = expected
}

Try / catch

path, err := item.PathForDownload(dir)
if err != nil && strings.Contains(err.Error(), "already downloaded") {
    os.Remove(item.State.DownloadPath)
    path, err = item.PathForDownload(dir)
}

Prevention

When it happens

Trigger: Downloading (even with --force) an item whose State.DownloadPath points somewhere else than the path derived from the current hub configuration — e.g. the install dir or item type mapping changed between runs.

Common situations: Moving or renaming the hub/install directories in config after items were downloaded; changing item type/stage so the computed path shifts; corrupted State from manual file moves.

Related errors


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