crowdsecurity/crowdsec · error

while getting security info: %w

Error message

while getting security info: %w

What it means

On Windows, setFilePerm restricts a file to owner/group access via Windows security descriptors. This error is returned when windows.GetNamedSecurityInfo fails to read the file's current security descriptor (OWNER_SECURITY_INFORMATION). Without the descriptor, CrowdSec cannot preserve the owner while rewriting the DACL.

Source

Thrown at pkg/database/file_utils_windows.go:16

package database

import (
	"fmt"
	"io/fs"

	log "github.com/sirupsen/logrus"
	"golang.org/x/sys/windows"
)

func setFilePerm(path string, mode fs.FileMode) error {
	//On windows, we don't care about the mode, just make sure the file is only readable/writable by the owner and group

	sd, err := windows.GetNamedSecurityInfo(path, windows.SE_FILE_OBJECT, windows.OWNER_SECURITY_INFORMATION)
	if err != nil {
		return fmt.Errorf("while getting security info: %w", err)
	}

	currentOwner, defaulted, err := sd.Owner()

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

	log.Debugf("current owner is %s (%v) (defaulted: %v)", currentOwner.String(), currentOwner, defaulted)

	currentGroup, defaulted, err := sd.Group()

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

	if currentGroup == nil {
		log.Debugf("current group is nil (defaulted: %v), using builtin admin instead", defaulted)

View on GitHub (pinned to 909b515798)

Solutions

  1. Move the CrowdSec data directory (db_path) to a local NTFS volume.
  2. Check the file exists and the service account has READ_CONTROL/ownership read rights on it.
  3. Exclude the CrowdSec data directory from antivirus interference and verify with icacls <path>.
  4. Check the wrapped error for ERROR_FILE_NOT_FOUND vs ERROR_ACCESS_DENIED to distinguish path vs permission causes.

Example fix

// before: blindly setting perm on a possibly-shared path
err := setFilePerm(dbPath, 0600)
// after: ensure NTFS-supporting local path first
if fi, ferr := os.Stat(dbPath); ferr != nil || !fi.Mode().IsRegular() {
	return fmt.Errorf("db path %s missing or invalid", dbPath)
}
err := setFilePerm(dbPath, 0600)
Defensive patterns

Strategy: validation

Validate before calling

// Go (Windows): verify path exists before perm change
if _, err := os.Stat(path); err != nil {
	return fmt.Errorf("file %s not available: %w", path, err)
}

Try / catch

err := setFilePerm(path, 0600)
if err != nil {
	log.Warnf("could not restrict permissions on %s: %v", path, err)
	// verify effective ACLs manually or relocate data dir
}

Prevention

When it happens

Trigger: Calling setFilePerm (invoked when writing SQLite DB / lock files on Windows) when GetNamedSecurityInfo fails: the path doesn't exist, the caller lacks READ_CONTROL on the file, or the path is on a filesystem not supporting ACLs (FAT32, network share).

Common situations: CrowdSec data directory placed on a FAT32/USB drive or network share without ACL support; antivirus or permissions blocking READ_CONTROL; file deleted between creation and perm setting.

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/87615921b978537c. Report an issue: GitHub.