ory/hydra · warning

file watch: %v

Error message

file watch: %v

What it means

In the same watcher loop, when a watcherx.ErrorEvent arrives (the file watcher itself failed — e.g. permission error, vanished directory, filesystem error), the event is wrapped as "file watch: %v" and forwarded to the error channel. It signals a problem watching the certificate files, not necessarily bad certificate content.

Source

Thrown at oryx/tlsx/cert.go:185

			select {
			case <-ctx.Done():
				return

			case event := <-events:
				var err error
				switch event := event.(type) {
				case *watcherx.ChangeEvent:
					var cert tls.Certificate
					cert, err = tls.LoadX509KeyPair(certPath, keyPath)
					if err == nil {
						store.Store(&cert)
						lastReportedError = ""
						continue
					}
					err = fmt.Errorf("unable to load X509 key pair from files: %v", err)

				case *watcherx.ErrorEvent:
					err = fmt.Errorf("file watch: %v", event)
				default:
					continue
				}

				if err.Error() == lastReportedError { // same message as before: don't spam the error channel
					continue
				}
				// fresh error
				select {
				case errs <- errors.WithStack(err):
					lastReportedError = err.Error()
				case <-time.After(500 * time.Millisecond):
				}
			}
		}
	}()

	return func(*tls.ClientHelloInfo) (*tls.Certificate, error) {

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Check that the watched cert/key paths still exist and remain accessible to the process
  2. Inspect the underlying watcher error in the message and fix the filesystem cause (permissions, mounts, inotify limits: fs.inotify.max_user_watches)
  3. Ensure secret volumes are not being unmounted/recreated in a way that removes the watched files
  4. Restart the service after the filesystem issue is resolved; the error channel consumer should log and keep the last good cert

Example fix

// before: consumer ignores error channel
// after
go func() {
    for err := range errCh {
        log.WithError(err).Warn("tls cert watcher problem") // e.g. "file watch: ..."
        // alert / check mounts
    }
}()
Defensive patterns

Strategy: try-catch

Try / catch

for err := range errCh {
    if strings.HasPrefix(err.Error(), "file watch:") {
        log.WithError(err).Warn("certificate file watcher error; check mounts/permissions/inotify limits")
    }
}

Prevention

When it happens

Trigger: A *watcherx.ErrorEvent is received while watching certPath/keyPath: watched file deleted, directory removed, permission revoked, or the underlying fsnotify backend errored.

Common situations: Kubernetes secret volume being swapped/recreated, tmpfs cleanup removing the watched path, container filesystem restrictions, or inotify limits exhausted on the host.

Related errors


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/dbef158b093f5537. Report an issue: GitHub.