{"record":{"id":"d65c2c733205959a","repo":"crowdsecurity/crowdsec","slug":"plugin-name-s-is-invalid-name-should-be-like-ty-d65c2c","errorCode":null,"errorMessage":"plugin name %s is invalid. Name should be like {type-name}","messagePattern":"plugin name (.+?) is invalid\\. Name should be like (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csplugin/utils_windows.go","lineNumber":224,"sourceCode":"\t}, nil\n}\n\nfunc (*PluginBroker) CreateCmd(ctx context.Context, binaryPath string) (*exec.Cmd, error) {\n\tvar err error\n\tcmd := exec.CommandContext(ctx, binaryPath)\n\tcmd.SysProcAttr, err = getProcessAttr()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"while getting process attributes: %w\", err)\n\t}\n\treturn cmd, err\n}\n\nfunc getPluginTypeAndSubtypeFromPath(path string) (string, string, error) {\n\tpluginFileName := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))\n\n\tparts := strings.Split(pluginFileName, \"-\")\n\tif len(parts) < 2 {\n\t\treturn \"\", \"\", fmt.Errorf(\"plugin name %s is invalid. Name should be like {type-name}\", path)\n\t}\n\treturn strings.Join(parts[:len(parts)-1], \"-\"), parts[len(parts)-1], nil\n}\n\nfunc pluginIsValid(path string) error {\n\tvar err error\n\n\t// check if it exists\n\tif _, err = os.Stat(path); err != nil {\n\t\treturn fmt.Errorf(\"plugin at %s does not exist\", path)\n\t}\n\n\t// check if it is owned by root\n\terr = CheckPerms(path)\n\tif err != nil {\n\t\treturn err\n\t}\n","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csplugin/utils_windows.go#L206-L242","documentation":"This error is thrown by getPluginTypeAndSubtypeFromPath when a notification plugin binary's filename does not split into at least two dash-separated parts. CrowdSec expects plugin binaries to be named {type-name}, e.g. 'notification-slack' where type='notification' and name='slack'; the type and subtype are derived purely from the filename.","triggerScenarios":"Calling getPluginTypeAndSubtypeFromPath (directly or via plugin loading in NewPluginWatcher) with a path whose base name, after stripping the extension, contains no '-' character, e.g. '/etc/crowdsec/plugins/slack' or '/usr/bin/myplugin'.","commonSituations":"Downloading a plugin binary and renaming it to drop the 'notification-' prefix; placing a plugin compiled from a module name without dashes; symlinking plugins with shortened names; Windows deployments where the plugin was copied under a custom filename.","solutions":["Rename the plugin binary to include a dash, format {type-name}, e.g. 'notification-slack' (type 'notification', subtype 'slack').","Place plugins in the configured plugin directory with the canonical name used by upstream CrowdSec plugin releases.","If it's a custom plugin, rebuild/rename the output binary so its file name matches the plugin type-name convention."],"exampleFix":"// before\n/etc/crowdsec/plugins/slack\n// after\n/etc/crowdsec/plugins/notification-slack","handlingStrategy":"validation","validationCode":"func pluginFilenameValid(path string) bool {\n\tbase := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))\n\treturn strings.Contains(base, \"-\") && strings.SplitN(base, \"-\", 2)[0] != \"\" && strings.SplitN(base, \"-\", 2)[1] != \"\"\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always keep the 'notification-<name>' naming convention when installing plugins","Never rename plugin binaries after download","Verify plugin filenames after packaging upgrades or manual copies"],"tags":["plugins","naming","configuration"],"backgroundTag":"invalid-argument-format","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"}