{"record":{"id":"e7180c5c7b785e01","repo":"crowdsecurity/crowdsec","slug":"empty-cti-key","errorCode":null,"errorMessage":"empty cti key","messagePattern":"empty cti key","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csconfig/api.go","lineNumber":81,"sourceCode":"\tInsecureSkipVerify  *bool              `yaml:\"insecure_skip_verify\"` // check if api certificate is bad or not\n\tUnregisterOnExit    bool               `yaml:\"unregister_on_exit,omitempty\"`\n}\n\ntype CTICfg struct {\n\tKey          *string        `yaml:\"key,omitempty\"`\n\tCacheTimeout *time.Duration `yaml:\"cache_timeout,omitempty\"`\n\tCacheSize    *int           `yaml:\"cache_size,omitempty\"`\n\tEnabled      *bool          `yaml:\"enabled,omitempty\"`\n\tLogLevel     log.Level      `yaml:\"log_level,omitempty\"`\n}\n\nfunc (a *CTICfg) Load() error {\n\tif a.Key == nil {\n\t\ta.Enabled = new(false)\n\t}\n\n\tif a.Key != nil && *a.Key == \"\" {\n\t\treturn errors.New(\"empty cti key\")\n\t}\n\n\tif a.Enabled == nil {\n\t\ta.Enabled = new(true)\n\t}\n\n\tif a.CacheTimeout == nil {\n\t\ta.CacheTimeout = new(time.Duration)\n\t\t*a.CacheTimeout = 10 * time.Minute\n\t}\n\n\tif a.CacheSize == nil {\n\t\ta.CacheSize = new(int)\n\t\t*a.CacheSize = 100\n\t}\n\n\treturn nil\n}","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csconfig/api.go#L63-L99","documentation":"CTICfg.Load validates the CrowdSec CTI integration configuration. If the api.cti.key is explicitly set to an empty string (key present in config but blank), the configuration is considered invalid and loading aborts. A nil key simply disables CTI; an empty key is treated as a misconfiguration.","triggerScenarios":"api.cti.key in config.yaml is set to '' (empty string); CTICfg.Load() is invoked during configuration loading and returns this error.","commonSituations":"Template or environment-variable substitution expanding to an empty value (e.g. CTI_KEY= empty env var rendered into the config); a user deleting the key contents but leaving the key; Helm/Docker config generation producing empty strings.","solutions":["Provide a real CTI API key from the CrowdSec console under api.cti.key","Remove the api.cti.key line entirely so CTI is cleanly disabled","If templating, ensure the value renders as YAML null or omit the key when empty"],"exampleFix":"// before\n# config.yaml\napi:\n  cti:\n    key: \"\"\n// after\n# config.yaml\napi:\n  cti:\n    enabled: false\n    key: \"<your-cti-api-key>\"","handlingStrategy":"validation","validationCode":"if cfg.CTI != nil && cfg.CTI.Key != nil && *cfg.CTI.Key == \"\" {\n    return errors.New(\"api.cti.key is set but empty; provide a key or remove it\")\n}\nif err := cfg.CTI.Load(); err != nil { ... }","typeGuard":"func ctiKeyPresent(k *string) bool { return k != nil && strings.TrimSpace(*k) != \"\" }","tryCatchPattern":"if err := apiCfg.CTI.Load(); err != nil {\n    return fmt.Errorf(\"invalid cti configuration: %w\", err)\n}","preventionTips":["Omit the key entirely rather than setting it to an empty string when disabling CTI","Validate templated configs so empty env substitutions fail fast","Keep CTI keys in secrets, not inline in config files"],"tags":["go","config","cti","crowdsec"],"backgroundTag":"empty-required-field","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"}