m1k1o/neko · error
unable to start file transfer dir watcher: %w
Error message
unable to start file transfer dir watcher: %w
What it means
Returned by filetransfer Manager.Start when fsnotify.NewWatcher() itself fails, so the directory watcher that keeps the file-transfer listing fresh cannot even be created. This is an OS/resource-level failure, not a problem with the configured directory.
Source
Thrown at server/internal/plugins/filetransfer/manager.go:148
func (m *Manager) Start() error {
// send init message once a user connects
m.sessions.OnConnected(func(session types.Session) {
m.sendUpdate(session)
})
// if file transfer is disabled, return immediately without starting the watcher
if !m.config.Enabled {
return nil
}
if _, err := os.Stat(m.config.RootDir); os.IsNotExist(err) {
err = os.Mkdir(m.config.RootDir, os.ModePerm)
m.logger.Err(err).Msg("creating file transfer directory")
}
watcher, err := fsnotify.NewWatcher()
if err != nil {
return fmt.Errorf("unable to start file transfer dir watcher: %w", err)
}
go func() {
defer watcher.Close()
// periodically refresh file list
ticker := time.NewTicker(m.config.RefreshInterval)
defer ticker.Stop()
for {
select {
case <-m.shutdown:
m.logger.Info().Msg("shutting down file transfer manager")
return
case <-ticker.C:
err, changed := m.refresh()
if err != nil {
m.logger.Err(err).Msg("unable to refresh file transfer list")View on GitHub (pinned to b0f01cedea)
Solutions
- Check and raise inotify limits: sysctl fs.inotify.max_user_watches and fs.inotify.max_user_instances (e.g. to 524288 / 512)
- Raise the process file-descriptor limit (ulimit -n / systemd LimitNOFILE)
- Verify the kernel/container supports inotify; in restricted containers run with a host-matching /proc/sys/fs/inotify
- Retry Start after freeing resources; if it persists, capture the wrapped %w error for the exact errno
Example fix
// before $ ulimit -n # 256 // after $ ulimit -n 65536 $ sudo sysctl -w fs.inotify.max_user_watches=524288
Defensive patterns
Strategy: fallback
Validate before calling
// preflight check for inotify availability
if _, err := os.Stat("/proc/sys/fs/inotify/max_user_watches"); err != nil {
log.Warn().Msg("inotify unavailable; file listing may be stale")
}
if n := readInt("/proc/sys/fs/inotify/max_user_instances"); n > 0 && n <= usedInstances() {
return fmt.Errorf("inotify instance limit reached (%d)", n)
} Try / catch
if err := m.Start(); err != nil {
if strings.Contains(err.Error(), "unable to start file transfer dir watcher") {
log.Error().Err(err).Msg("increase fs.inotify limits or fd ulimit")
// degrade: run with periodic polling instead of a watcher
}
return err
} Prevention
- Raise fs.inotify.max_user_watches and max_user_instances on hosts running many watchers
- Set LimitNOFILE high in the systemd unit for the server
- Test plugin Start inside the actual container image — minimal kernels may lack inotify
When it happens
Trigger: Manager.Start runs and fsnotify.NewWatcher() returns an error — typically fd/inotify watch limits exhausted (EMFILE/ENOSPC), or running in a container/kernel without inotify support.
Common situations: Long-running servers hitting fs.inotify.max_user_watches / max_user_instances limits; minimal containers or sandboxes without inotify; low file-descriptor ulimits.
Related errors
- unable to watch file transfer dir: %w
- image data not found
- screencast not enabled
- unable to get first image
- timeouted while waiting for first image
AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01).
Data as JSON: /api/errors/de89eb6a09a76e42.
Report an issue: GitHub.