crowdsecurity/crowdsec · error

could not lstat() file %s: %w

Error message

could not lstat() file %s: %w

What it means

setupTailForFile calls os.Lstat to check whether the path is a symlink and warn about rotation-detection limitations. If Lstat fails it returns "could not lstat() file %s: %w". Like the Stat error, this means the path became inaccessible (or was always inaccessible to stat) between the earlier open and this check.

Source

Thrown at pkg/acquisition/modules/file/run.go:252

	} else {
		networkFS, fsType, err := fsutil.IsNetworkFS(file)
		if err != nil {
			logger.Warningf("Could not get fs type for %s : %s", file, err)
		}

		logger.Debugf("fs for %s is network: %t (%s)", file, networkFS, fsType)

		if networkFS {
			logger.Warnf("Disabling inotify polling on %s as it is on a network share. You can manually set poll_without_inotify to true to make this message disappear, or to false to enforce inotify poll", file)

			pollFile = true
		}
	}

	// Check symlink status
	filink, err := os.Lstat(file)
	if err != nil {
		return fmt.Errorf("could not lstat() file %s: %w", file, err)
	}

	if filink.Mode()&os.ModeSymlink == os.ModeSymlink && !pollFile {
		logger.Warnf("File %s is a symlink, but inotify polling is enabled. Crowdsec will not be able to detect rotation. Consider setting poll_without_inotify to true in your configuration", file)
	}

	// Create the tailer with appropriate configuration
	seekInfo := &tail.SeekInfo{Offset: 0, Whence: io.SeekEnd}
	if s.config.Mode == configuration.CAT_MODE {
		seekInfo.Whence = io.SeekStart
	}

	if seekEnd {
		seekInfo.Whence = io.SeekEnd
	}

	logger.Infof("Starting tail (offset: %d, whence: %d)", seekInfo.Offset, seekInfo.Whence)

View on GitHub (pinned to 909b515798)

Solutions

  1. Check whether the path (or symlink) still exists: ls -la the path.
  2. If it's a dangling symlink, fix or remove it from the acquisition patterns.
  3. Verify parent directory execute permissions for the crowdsec user.
  4. If the file races constantly with rotation, set poll_without_inotify: true in the acquisition config.
Defensive patterns

Strategy: validation

Validate before calling

// verify path is a resolvable, existing entry
ls -la /var/log/myapp.log
readlink -f /var/log/myapp.log || echo 'dangling symlink'

Prevention

When it happens

Trigger: os.Lstat(file) errors in setupTailForFile during symlink status check, from StreamingAcquisition or checkAndTailFile.

Common situations: Symlink target replaced/removed mid-scan; dangling symlink where the target vanished; permission on symlink resolution; NFS staleness.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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