{"record":{"id":"f54145252949bb4c","repo":"crowdsecurity/crowdsec","slug":"empty-file","errorCode":null,"errorMessage":"empty file","messagePattern":"empty file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csconfig/api.go","lineNumber":458,"sourceCode":"\t\t}\n\t}\n\n\treturn nil\n}\n\n// we cannot unmarshal to type net.IPNet, so we need to do it manually\ntype capiWhitelists struct {\n\tIps   []string `yaml:\"ips\"`\n\tCidrs []string `yaml:\"cidrs\"`\n}\n\nfunc parseCapiWhitelists(fd io.Reader) (*CapiWhitelist, error) {\n\tfromCfg := capiWhitelists{}\n\n\tdecoder := yaml.NewDecoder(fd)\n\tif err := decoder.Decode(&fromCfg); err != nil {\n\t\tif errors.Is(err, io.EOF) {\n\t\t\treturn nil, errors.New(\"empty file\")\n\t\t}\n\n\t\treturn nil, err\n\t}\n\n\tret := &CapiWhitelist{\n\t\tIps:   make([]netip.Addr, len(fromCfg.Ips)),\n\t\tCidrs: make([]netip.Prefix, len(fromCfg.Cidrs)),\n\t}\n\n\tfor idx, v := range fromCfg.Ips {\n\t\tip, err := netip.ParseAddr(v)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tret.Ips[idx] = ip\n\t}","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csconfig/api.go#L440-L476","documentation":"parseCapiWhitelists reads a CAPI whitelist YAML file and rejects files that contain no YAML documents. The YAML decoder returns io.EOF for an empty stream, which the loader translates into a clear 'empty file' error instead of silently producing an empty whitelist.","triggerScenarios":"Loading a capi whitelist file (via LoadCapiWhitelists) whose content is zero bytes or only comments/whitespace; decoder.Decode returns io.EOF.","commonSituations":"An empty whitelist file created by touch or truncated by a failed write; a config management tool templating an empty whitelist; mounting an empty file into a container config dir.","solutions":["Add valid whitelist content (e.g. 'capecs: []' / 'cves: []' or the expected keys) to the file","Delete the whitelist file or remove its config reference if it is not needed","Restore the file from backup if it was truncated"],"exampleFix":"// before\n# /etc/crowdsec/capi-whitelists.yaml (0 bytes)\n// after\n# /etc/crowdsec/capi-whitelists.yaml\ncapecs: []\ncves: []","handlingStrategy":"fallback","validationCode":"info, err := os.Stat(path)\nif err != nil || info.Size() == 0 {\n    // skip loading or create a valid skeleton whitelist file\n}","typeGuard":null,"tryCatchPattern":"wl, err := LoadCapiWhitelists(path)\nif err != nil {\n    if strings.Contains(err.Error(), \"empty file\") {\n        wl = &CapiWhitelist{} // treat as no whitelists\n    } else {\n        return err\n    }\n}","preventionTips":["Ship a skeleton whitelist file with valid keys instead of an empty file","Check file size after templating/CI writes","Use atomic writes (write temp + rename) to avoid truncated files"],"tags":["go","config","yaml","whitelist"],"backgroundTag":"empty-file","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}