{"record":{"id":"7c994137d1d492b6","repo":"crowdsecurity/crowdsec","slug":"s-s-has-no-index-metadata","errorCode":null,"errorMessage":"%s:%s has no index metadata","messagePattern":"(.+?):(.+?) has no index metadata","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/cwhub/hub.go","lineNumber":86,"sourceCode":"}\n\n// parseIndex takes the content of an index file and fills the map of associated parsers/scenarios/collections.\nfunc (h *Hub) parseIndex() error {\n\tbidx, err := os.ReadFile(h.local.HubIndexFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to read index file: %w\", err)\n\t}\n\n\tif err := json.Unmarshal(bidx, &h.items); err != nil {\n\t\treturn fmt.Errorf(\"failed to parse index: %w\", err)\n\t}\n\n\t// Iterate over the different types to complete the struct\n\tfor _, itemType := range ItemTypes {\n\t\tfor name, item := range h.GetItemMap(itemType) {\n\t\t\tif item == nil {\n\t\t\t\t// likely defined as empty object or null in the index file\n\t\t\t\treturn fmt.Errorf(\"%s:%s has no index metadata\", itemType, name)\n\t\t\t}\n\n\t\t\tif item.RemotePath == \"\" {\n\t\t\t\treturn fmt.Errorf(\"%s:%s has no download path\", itemType, name)\n\t\t\t}\n\n\t\t\tif (itemType == PARSERS || itemType == POSTOVERFLOWS) && item.Stage == \"\" {\n\t\t\t\treturn fmt.Errorf(\"%s:%s has no stage\", itemType, name)\n\t\t\t}\n\n\t\t\titem.hub = h\n\t\t\titem.Name = name\n\n\t\t\titem.Type = itemType\n\t\t\titem.FileName = path.Base(item.RemotePath)\n\n\t\t\titem.logMissingSubItems()\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/cwhub/hub.go#L68-L104","documentation":"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.","triggerScenarios":"Hub.Load → parseIndex when the index file contains entries like `\"crowdsecurity/nginx\": {}` or `null` for some item type/name.","commonSituations":"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.","solutions":["Run `sudo cscli hub update` to obtain a complete index","Locate the offending entry in .index.json (`jq` over each item type) to confirm it is empty/null","Restore the index from a fresh download rather than hand-editing it","Report a hub publishing issue to CrowdSec if a fresh index still contains the empty entry"],"exampleFix":"// before (.index.json)\n\"crowdsecurity/nginx\": {}\n// after: re-download instead of editing\nsudo cscli hub update","handlingStrategy":"validation","validationCode":"for _, itemType := range cwhub.ItemTypes {\n    for name, item := range hub.GetItemMap(itemType) {\n        if item == nil || item.RemotePath == \"\" {\n            return fmt.Errorf(\"index entry %s:%s incomplete; run 'cscli hub update'\", itemType, name)\n        }\n    }\n}","typeGuard":"func indexEntryValid(item *cwhub.Item) bool { return item != nil && item.RemotePath != \"\" }","tryCatchPattern":"if err := hub.Load(); err != nil {\n    if strings.Contains(err.Error(), \"has no index metadata\") {\n        logger.Error(\"broken index entries; refreshing index via 'cscli hub update'\")\n        return refreshHubIndex(ctx)\n    }\n    return err\n}","preventionTips":["Never submit or hand-craft index entries with empty objects/null values","Refresh the index from the official hub rather than editing locally","Report persistently empty hub entries upstream to CrowdSec"],"tags":["hub","index","validation","metadata"],"backgroundTag":"schema-validation-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}