crowdsecurity/crowdsec · error

while getting owner security info: %w

Error message

while getting owner security info: %w

What it means

CheckPerms queries the plugin file's security descriptor with windows.GetNamedSecurityInfo(SE_FILE_OBJECT, OWNER|DACL), the Win32 GetNamedSecurityInfo API. This error wraps a failure of that call, meaning Windows could not return the object's owner and DACL information — typically an OS error like ERROR_ACCESS_DENIED, ERROR_FILE_NOT_FOUND, or ERROR_INVALID_OWNER.

Source

Thrown at pkg/csplugin/utils_windows.go:84

	adminSid, err := windows.CreateWellKnownSid(windows.WELL_KNOWN_SID_TYPE(windows.WinBuiltinAdministratorsSid))
	if err != nil {
		return fmt.Errorf("while creating built-in Administrators well known sid: %w", err)
	}

	currentUser, err := user.Current()
	if err != nil {
		return fmt.Errorf("while getting current user: %w", err)
	}

	currentUserSid, _, _, err := windows.LookupSID("", currentUser.Username)

	if err != nil {
		return fmt.Errorf("while looking up current user sid: %w", err)
	}

	sd, err := windows.GetNamedSecurityInfo(path, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION)
	if err != nil {
		return fmt.Errorf("while getting owner security info: %w", err)
	}
	if !sd.IsValid() {
		return errors.New("security descriptor is invalid")
	}
	owner, _, err := sd.Owner()
	if err != nil {
		return fmt.Errorf("while getting owner: %w", err)
	}
	if !owner.IsValid() {
		return errors.New("owner is invalid")
	}

	if !owner.Equals(systemSid) && !owner.Equals(currentUserSid) && !owner.Equals(adminSid) {
		return fmt.Errorf("plugin at %s is not owned by SYSTEM, Administrators or by current user, but by %s", path, owner.String())
	}

	dacl, _, err := sd.DACL()
	if err != nil {

View on GitHub (pinned to 909b515798)

Solutions

  1. Verify the plugin file still exists at the path and is on an NTFS volume that supports ACLs
  2. Run crowdsec under an account with READ_CONTROL access to the plugin directory, or fix the ACLs on the plugin files
  3. Check antivirus/EDR software isn't blocking security-descriptor queries on the plugin path
  4. Read the wrapped %w Win32 error to distinguish not-found vs access-denied and act accordingly

Example fix

// before
sd, err := windows.GetNamedSecurityInfo(path, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION)
if err != nil {
	return fmt.Errorf("while getting owner security info: %w", err)
}
// after
if _, err := os.Stat(path); err != nil {
	return fmt.Errorf("plugin vanished before security check: %w", err)
}
sd, err := windows.GetNamedSecurityInfo(path, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION|windows.DACL_SECURITY_INFORMATION)
if err != nil {
	return fmt.Errorf("while getting owner security info for %s: %w", path, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if fi, err := os.Stat(path); err != nil {
	return fmt.Errorf("plugin missing: %w", err)
} else if fi.Mode()&os.ModeType != 0 {
	return errors.New("path is not a regular file")
}

Try / catch

err := CheckPerms(pluginPath)
var errno windows.Errno
if err != nil && errors.As(err, &errno) && errno == windows.ERROR_ACCESS_DENIED {
	return fmt.Errorf("grant READ_CONTROL on %s to the crowdsec account", pluginPath)
}

Prevention

When it happens

Trigger: Calling CheckPerms on a path where GetNamedSecurityInfo fails: the file was deleted between the earlier os.Stat and this call; the caller lacks READ_CONTROL on the file; the path is malformed or on a filesystem that doesn't support NT security descriptors (FAT32, some network shares).

Common situations: Plugin directory on a FAT32/exFAT volume or network share without NT ACL support; antivirus or EDR blocking security-descriptor queries; race where the plugin binary is replaced/removed while crowdsec scans; crowdsec run by an account with no read-control access to the plugin file.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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