{"record":{"id":"0759274fd7fd741c","repo":"crowdsecurity/crowdsec","slug":"could-not-create-fsnotify-watcher-w","errorCode":null,"errorMessage":"could not create fsnotify watcher: %w","messagePattern":"could not create fsnotify watcher: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/acquisition/modules/file/config.go","lineNumber":90,"sourceCode":"\treturn nil\n}\n\nfunc (s *Source) Configure(_ context.Context, yamlConfig []byte, logger *log.Entry, metricsLevel metrics.AcquisitionMetricsLevel) error {\n\ts.logger = logger\n\ts.metricsLevel = metricsLevel\n\n\terr := s.UnmarshalConfig(yamlConfig)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ts.watchedDirectories = make(map[string]bool)\n\ts.tailMapMutex = &sync.RWMutex{}\n\ts.tails = make(map[string]bool)\n\n\ts.watcher, err = fsnotify.NewWatcher()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not create fsnotify watcher: %w\", err)\n\t}\n\n\ts.logger.Tracef(\"Actual FileAcquisition Configuration %+v\", s.config)\n\n\tfor _, pattern := range s.config.Filenames {\n\t\tif s.config.ForceInotify {\n\t\t\tdirectory := filepath.Dir(pattern)\n\t\t\ts.logger.Infof(\"Force add watch on %s\", directory)\n\n\t\t\tif !s.watchedDirectories[directory] {\n\t\t\t\terr = s.watcher.Add(directory)\n\t\t\t\tif err != nil {\n\t\t\t\t\ts.logger.Errorf(\"Could not create watch on directory %s : %s\", directory, err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\ts.watchedDirectories[directory] = true\n\t\t\t}","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/acquisition/modules/file/config.go#L72-L108","documentation":"Configure creates the fsnotify watcher with fsnotify.NewWatcher(); if the OS refuses (inotify instances/watches exhausted on Linux, or kqueue limitations), it returns \"could not create fsnotify watcher: %w\". This happens before any directory watch is added, so the whole file datasource fails to start.","triggerScenarios":"fsnotify.NewWatcher() returning an OS error: Linux inotify instances exhausted (fs.inotify.max_user_instances reached by this process/container), or running in a container/namespace where inotify is unavailable.","commonSituations":"Containers with low inotify limits (common in Kubernetes pods); many concurrent watchers on one host (IDEs, other agents) draining max_user_instances; LXC/WSL1 environments lacking inotify support.","solutions":["Raise the kernel limit: `sudo sysctl fs.inotify.max_user_instances=1024` (and max_user_watches=1048576) and persist it in /etc/sysctl.conf.","In containers/K8s, raise the host-level sysctl or use a privileged/sysctl-tolerant pod spec.","As a fallback, set poll_without_inotify: true in the file source config to poll instead of using inotify.","Check current usage: `sysctl fs.inotify.max_user_instances` vs. per-user inotify instances (`find /proc/*/fd -lname anon_inode:inotify | wc -l`)."],"exampleFix":"// kernel tuning\nsudo sysctl -w fs.inotify.max_user_instances=1024\n// or config fallback (acquis.yaml)\nsource: file\npoll_without_inotify: true\nfilenames:\n  - /var/log/*.log","handlingStrategy":"fallback","validationCode":"// Go: probe inotify availability before configuring the watcher\ninst, err := os.ReadFile(\"/proc/sys/fs/inotify/max_user_instances\")\nif err == nil {\n\tif n, _ := strconv.Atoi(strings.TrimSpace(string(inst))); n > 0 && n <= usedInstances() {\n\t\tcfg.PollWithoutInotify = boolPtr(true) // fall back to polling\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := src.Configure(ctx, cfgYAML, logger, metricsLevel); err != nil {\n\tif strings.Contains(err.Error(), \"could not create fsnotify watcher\") {\n\t\t// raise fs.inotify.max_user_instances or switch to poll_without_inotify: true\n\t}\n}","preventionTips":["Set generous fs.inotify.max_user_instances/max_user_watches on hosts running many watchers.","Set poll_without_inotify: true in containers known to have tight inotify limits.","Monitor inotify usage (`find /proc/*/fd -lname anon_inode:inotify | wc -l`) in capacity checks.","Verify inotify works at container startup with a smoke test before going live."],"tags":["inotify","fsnotify","file-source","kernel-limits"],"backgroundTag":"resource-limit-exceeded","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}