crowdsecurity/crowdsec · error

while getting process attributes: both plugin user and group

Error message

while getting process attributes: both plugin user and group must be set

What it means

PluginBroker.CreateCmd can run notification plugins under a dedicated OS user/group via SysProcAttr credentials. The config allows specifying user and group independently, but dropping privileges on POSIX requires both; specifying only one is ambiguous, so CreateCmd rejects it before spawning.

Source

Thrown at pkg/csplugin/utils.go:27

	"io/fs"
	"math"
	"os"
	"os/exec"
	"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

View on GitHub (pinned to 909b515798)

Solutions

  1. Set both keys in the plugin process config: user: crowdsec, group: crowdsec (or the desired uid/gid names)
  2. If you do not need privilege dropping, remove both user and group so the plugin runs as the crowdsec process user
  3. Verify the user and group exist on the system (getent passwd <user>; getent group <group>)

Example fix

// before (config.yaml)
plugin_config:
  user: crowdsec

// after
plugin_config:
  user: crowdsec
  group: crowdsec
Defensive patterns

Strategy: validation

Validate before calling

if (pc.User == "") != (pc.Group == "") {
    return fmt.Errorf("plugin user and group must both be set (got user=%q group=%q)", pc.User, pc.Group)
}

Try / catch

if _, err := broker.CreateCmd(ctx, binPath); err != nil {
    if strings.Contains(err.Error(), "both plugin user and group must be set") {
        log.Fatal("set both user and group in the plugin process config, or neither")
    }
    return err
}

Prevention

When it happens

Trigger: A plugin_common or plugin-specific config that sets 'user:' without 'group:' (or vice versa), when loadNotificationPlugin spawns the plugin binary.

Common situations: Hardening guides telling users to set a plugin user but omitting the group line; templated configs where one of the two fields is left blank.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/67e07db11aae1ac2. Report an issue: GitHub.