crowdsecurity/crowdsec · error
while getting process attributes: %w
Error message
while getting process attributes: %w
What it means
CreateCmd wraps any failure from getProcessAttr, which resolves the configured plugin user/group to uid/gid values via os/user lookups. The wrapper preserves the underlying cause (%w) while attributing it to the plugin process-attribute setup step. It only fires when both user and group are configured for the notification plugin.
Source
Thrown at pkg/csplugin/utils.go:31
"os/user"
"path/filepath"
"strconv"
"strings"
"syscall"
"golang.org/x/sys/unix"
)
func (pb *PluginBroker) CreateCmd(ctx context.Context, binaryPath string) (*exec.Cmd, error) {
var err error
cmd := exec.CommandContext(ctx, binaryPath)
if pb.pluginProcConfig.User != "" || pb.pluginProcConfig.Group != "" {
if pb.pluginProcConfig.User == "" || pb.pluginProcConfig.Group == "" {
return nil, errors.New("while getting process attributes: both plugin user and group must be set")
}
cmd.SysProcAttr, err = getProcessAttr(pb.pluginProcConfig.User, pb.pluginProcConfig.Group)
if err != nil {
return nil, fmt.Errorf("while getting process attributes: %w", err)
}
cmd.SysProcAttr.Credential.NoSetGroups = true
}
return cmd, err
}
func getUID(username string) (uint32, error) {
u, err := user.Lookup(username)
if err != nil {
return 0, err
}
uid, err := strconv.ParseInt(u.Uid, 10, 32)
if err != nil {
return 0, err
}
if uid < 0 || uid > math.MaxInt32 {
return 0, errors.New("out of bound uid")
}View on GitHub (pinned to 909b515798)
Solutions
- Check which user/group is configured for the plugin and verify it exists on the host: getent passwd <user> and getent group <group>
- Create the missing user/group, or remove/adjust the user and group keys in the plugin's config so they match an existing account
- Read the wrapped %w cause in the full error chain to see whether it was the user or the group lookup that failed
Example fix
# before (config/auth.yaml) name: crowdsecurity/http user: crowdsec group: crowdsec # after name: crowdsecurity/http user: www-data group: www-data
Defensive patterns
Strategy: validation
Validate before calling
if cfg.User != "" || cfg.Group != "" {
if _, err := user.Lookup(cfg.User); err != nil {
return fmt.Errorf("plugin user %q does not exist", cfg.User)
}
if _, err := user.LookupGroup(cfg.Group); err != nil {
return fmt.Errorf("plugin group %q does not exist", cfg.Group)
}
} Try / catch
cmd, err := CreateCmd(...)
if err != nil {
var ue *user.UnknownUserError
if errors.As(err, &ue) { log.Fatalf("create plugin user first: %v", ue) }
return err
} Prevention
- Always create the plugin user/group (useradd/groupadd) before enabling user/group keys in the plugin config
- Keep the configured user/group identical across environments (bake into container images)
- Never set only one of user/group — both are required
When it happens
Trigger: loadNotificationPlugin calls CreateCmd with pluginProcConfig.User and pluginProcConfig.Group both set, and getProcessAttr fails because the username or groupname cannot be resolved to a uid/gid on the system (or the underlying unix call otherwise errors).
Common situations: config/auth.yaml (or profiles notification_config) specifies a 'user'/'group' for a plugin that does not exist on the host, e.g. copied config from another machine referencing 'crowdsec' user before it was created; running in a container where the user/group entries are absent from /etc/passwd or /etc/group.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
- plugin name %s is invalid. Name should be like {type-name}
- empty cti key
- cannot use TLS with a unix socket
- user/password authentication and TLS authentication are mutu
- no listen_uri or listen_socket specified
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/d8e60cdc7f9493bc.
Report an issue: GitHub.