crowdsecurity/crowdsec · error

%s:%s has no index metadata

Error message

%s:%s has no index metadata

What it means

During parseIndex, after unmarshalling, every item entry for each ItemTypes is validated. A nil item means the index JSON defined the entry as an empty object or null, so there is no metadata to populate, and the index is declared invalid.

Source

Thrown at pkg/cwhub/hub.go:86

}

// parseIndex takes the content of an index file and fills the map of associated parsers/scenarios/collections.
func (h *Hub) parseIndex() error {
	bidx, err := os.ReadFile(h.local.HubIndexFile)
	if err != nil {
		return fmt.Errorf("unable to read index file: %w", err)
	}

	if err := json.Unmarshal(bidx, &h.items); err != nil {
		return fmt.Errorf("failed to parse index: %w", err)
	}

	// Iterate over the different types to complete the struct
	for _, itemType := range ItemTypes {
		for name, item := range h.GetItemMap(itemType) {
			if item == nil {
				// likely defined as empty object or null in the index file
				return fmt.Errorf("%s:%s has no index metadata", itemType, name)
			}

			if item.RemotePath == "" {
				return fmt.Errorf("%s:%s has no download path", itemType, name)
			}

			if (itemType == PARSERS || itemType == POSTOVERFLOWS) && item.Stage == "" {
				return fmt.Errorf("%s:%s has no stage", itemType, name)
			}

			item.hub = h
			item.Name = name

			item.Type = itemType
			item.FileName = path.Base(item.RemotePath)

			item.logMissingSubItems()

View on GitHub (pinned to 909b515798)

Solutions

  1. Run `sudo cscli hub update` to obtain a complete index
  2. Locate the offending entry in .index.json (`jq` over each item type) to confirm it is empty/null
  3. Restore the index from a fresh download rather than hand-editing it
  4. Report a hub publishing issue to CrowdSec if a fresh index still contains the empty entry

Example fix

// before (.index.json)
"crowdsecurity/nginx": {}
// after: re-download instead of editing
sudo cscli hub update
Defensive patterns

Strategy: validation

Validate before calling

for _, itemType := range cwhub.ItemTypes {
    for name, item := range hub.GetItemMap(itemType) {
        if item == nil || item.RemotePath == "" {
            return fmt.Errorf("index entry %s:%s incomplete; run 'cscli hub update'", itemType, name)
        }
    }
}

Type guard

func indexEntryValid(item *cwhub.Item) bool { return item != nil && item.RemotePath != "" }

Try / catch

if err := hub.Load(); err != nil {
    if strings.Contains(err.Error(), "has no index metadata") {
        logger.Error("broken index entries; refreshing index via 'cscli hub update'")
        return refreshHubIndex(ctx)
    }
    return err
}

Prevention

When it happens

Trigger: Hub.Load → parseIndex when the index file contains entries like `"crowdsecurity/nginx": {}` or `null` for some item type/name.

Common situations: Manually edited index, hub-side publishing of a broken/placeholder entry, or an index truncated in a way that JSON still parses but with empty values.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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