AdguardTeam/AdGuardHome · error
starting watcher: %w
Error message
starting watcher: %w
What it means
Failed to start the underlying fsnotify watcher that monitors TLS certificate files for changes. The wrapped error comes from watcher.Start, usually an OS-level failure to initialize inotify/ReadDirectoryChangesW.
Source
Thrown at internal/aghtls/defaultmanager.go:257
// Refresh implements the [service.Refresher] interface for *DefaultManager.
func (mgr *DefaultManager) Refresh(ctx context.Context) (err error) {
mgr.logger.DebugContext(ctx, "refreshing")
select {
case mgr.updates <- UpdateSignal{}:
return nil
case <-ctx.Done():
return fmt.Errorf("refreshing: %w", ctx.Err())
default:
return nil
}
}
// Start implements the [service.Interface] interface for *DefaultManager.
func (mgr *DefaultManager) Start(ctx context.Context) (err error) {
err = mgr.watcher.Start(ctx)
if err != nil {
return fmt.Errorf("starting watcher: %w", err)
}
go mgr.handleEvents(ctx)
go mgr.handleCertFileChange(ctx)
return nil
}
// Shutdown implements the [service.Interface] interface for *DefaultManager.
func (mgr *DefaultManager) Shutdown(ctx context.Context) (err error) {
defer close(mgr.updates)
err = mgr.watcher.Shutdown(ctx)
if err != nil {
return fmt.Errorf("shutting down watcher: %w", err)
}
return nilView on GitHub (pinned to b41aefbe51)
Solutions
- Raise fs.inotify.max_user_instances if the OS reports too many inotify instances
- Check for fd leaks (lsof) if ENOMEM/EMFILE appears in the wrapped error
- Ensure Start is called exactly once per manager lifecycle
Defensive patterns
Strategy: try-catch
Validate before calling
if rlimitCheck() { /* ensure fds available */ } Try / catch
if err := mgr.Start(ctx); err != nil {
log.Fatal("tls manager failed to start", "err", err) // service cannot hot-reload certs
} Prevention
- Call Start exactly once per manager
- Raise fs.inotify.max_user_instances in container hosts
- Avoid leaking file descriptors before Start
When it happens
Trigger: Calling DefaultManager.Start(ctx) when the fsnotify backend cannot create an inotify instance (fd exhaustion, inotify instances limit fs.inotify.max_user_instances) or after the watcher was already started/shut down.
Common situations: Running in a resource-constrained container with a low max_user_instances limit; file-descriptor exhaustion from leaking watchers; calling Start twice on the same manager.
Related errors
- watching %s %s: %w
- unwatching %s %s: %w
- shutting down watcher: %w
- reading cert file: %w
- validating tcp ports: %w
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/d1889297f7125548.
Report an issue: GitHub.