crowdsecurity/crowdsec · error

failed to sync %s: %w

Error message

failed to sync %s: %w

What it means

localSync refreshes the hub state by scanning the hub directory (downloaded items) first; any error returned by syncDir is wrapped as 'failed to sync <HubDir>'. This means walking/collecting items under the hub working directory failed, so the whole Load aborts with the inner cause (bad path layout, unreadable file, etc.) prefixed by the directory that failed.

Source

Thrown at pkg/cwhub/sync.go:514

	for _, v := range sl {
		if _, ok := seen[v]; ok {
			continue
		}

		seen[v] = struct{}{}
		sl[j] = v
		j++
	}

	return sl[:j]
}

// localSync updates the hub state with downloaded, installed and local items.
func (h *Hub) localSync() error {
	// add downloaded files first, so they can find the place in the index
	// before it's overridden by local items in case of name collision
	if err := h.syncDir(h.local.HubDir); err != nil {
		return fmt.Errorf("failed to sync %s: %w", h.local.HubDir, err)
	}

	if err := h.syncDir(h.local.InstallDir); err != nil {
		return fmt.Errorf("failed to sync %s: %w", h.local.InstallDir, err)
	}

	warnings := make([]string, 0)

	for _, item := range h.GetItemMap(COLLECTIONS) {
		// check for cyclic dependencies
		subs, err := item.descendants()
		if err != nil {
			return err
		}

		// populate the sub- and sub-sub-items with the collections they belong to
		for _, sub := range subs {
			sub.State.BelongsToCollections = insertInOrderNoCase(sub.State.BelongsToCollections, item.Name)

View on GitHub (pinned to 909b515798)

Solutions

  1. Read the inner wrapped error (%w) to identify the offending file, and fix it per that specific cause
  2. Reset the hub state: 'cscli hub update' then 'cscli hub upgrade' to restore a clean tree
  3. Verify HUBDIR in config.yaml points to the correct hub working directory with the expected layout

Example fix

// before: config.yaml
hub_dir: /etc/crowdsec/data/hub  # wrong: tree lacking <type>/<author>/<file> depth
// after
hub_dir: /etc/crowdsec/hub
cscli hub update
Defensive patterns

Strategy: try-catch

Validate before calling

func checkHubDir(hubDir string) error {
	info, err := os.Stat(hubDir)
	if err != nil {
		return err
	}
	if !info.IsDir() {
		return fmt.Errorf("%s is not a directory", hubDir)
	}
	return nil
}
// also confirm config.yaml hub_dir matches 'cscli hub list' expectations

Try / catch

if err := hub.Load(ctx); err != nil {
	if strings.Contains(err.Error(), "failed to sync "+hubDir) {
		return fmt.Errorf("hub dir broken (%v); run 'cscli hub update'", errors.Unwrap(err))
	}
	return err
}

Prevention

When it happens

Trigger: Hub.Load calls localSync; syncDir(h.local.HubDir) returns an error from any item visited under the hub dir, e.g. newHubItemSpec path errors, unreadable files, or a broken walk due to permissions.

Common situations: Corrupted or hand-modified hub directory tree; hub dir partially deleted while crowdsec starts; hub dir on a mount that lost permissions; running with a HUBDIR pointing at a nonexistent or wrong-depth tree.

Related errors


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