crowdsecurity/crowdsec · error
could not start tailing file %s : %w
Error message
could not start tailing file %s : %w
What it means
This is the tail.Init failure path in setupTailForFile: the hpcloud/tail library could not start following the file (given Follow, Poll, Location seekInfo options). It wraps the tail library's own error, which commonly is that the file no longer exists or can't be re-opened by the tailer.
Source
Thrown at pkg/acquisition/modules/file/run.go:279
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)
tail, err := tail.TailFile(file, tail.Config{
ReOpen: true,
Follow: true,
Poll: pollFile,
Location: seekInfo,
Logger: log.NewEntry(log.StandardLogger()),
})
if err != nil {
return fmt.Errorf("could not start tailing file %s : %w", file, err)
}
s.tailMapMutex.Lock()
s.tails[file] = true
s.tailMapMutex.Unlock()
t.Go(func() error {
defer trace.ReportPanic()
return s.tailFile(out, t, tail)
})
return nil
}
func (s *Source) tailFile(out chan pipeline.Event, t *tomb.Tomb, tail *tail.Tail) error {
logger := s.logger.WithField("tail", tail.Filename)
logger.Debug("-> start tailing")
View on GitHub (pinned to 909b515798)
Solutions
- Read the wrapped tail error in the log for the concrete cause (often 'file not found').
- Ensure the file exists and is readable at tail setup time.
- If logs rotate aggressively, enable poll_without_inotify / poll mode so rotation is handled gracefully.
- Check ulimit -n for the crowdsec process; each tailed file holds a descriptor.
Example fix
// acquis.yaml before source: file filenames: - /var/log/app.log // after (tolerate rotation) source: file filenames: - /var/log/app.log poll_without_inotify: true
Defensive patterns
Strategy: try-catch
Validate before calling
function canTail(path) {
return fs.existsSync(path) && fs.statSync(path).isFile();
} Try / catch
// retry tail init on transient races
for i := 0; i < 3; i++ {
if err := setupTailForFile(...); err == nil { break }
time.Sleep(time.Second)
} Prevention
- Enable poll mode (poll_without_inotify) for aggressively rotated logs.
- Raise ulimit -n for the crowdsec process when tailing many files.
- Ensure files exist before acquisition start or use globs to pick them up later.
When it happens
Trigger: tail.TailFile(file, tail.Config{Follow:true, Poll:pollFile, Location:seekInfo, ...}) returns an error in setupTailForFile, called by StreamingAcquisition/checkAndTailFile.
Common situations: File deleted between validation and tail init; seek offset (Location) beyond file size after rotation/truncation with incompatible tail mode; permissions revoked; too many open files for the tailer.
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
- unable to read %s : %s
- unable to close %s : %s
- could not lstat() file %s: %w
- failed opening %s: %w
- failed to read gz %s: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/aeaf23ce3ccf7ad7.
Report an issue: GitHub.