ipn/localapi: stop logging "broken pipe" errors (#18487)

The Tailscale CLI has some methods to watch the IPN bus for
messages, say, the current netmap (`tailscale debug netmap`).
The Tailscale daemon supports this using a streaming HTTP
response. Sometimes, the client can close its connection
abruptly -- due to an interruption, or in the case of `debug netmap`,
intentionally after consuming one message.

If the server daemon is writing a response as the client closes
its end of the socket, the daemon typically encounters a "broken pipe"
error. The "Watch IPN Bus" handler currently logs such errors after
they're propagated by a JSON encoding/writer helper.

Since the Tailscale CLI nominally closes its socket with the daemon
in this slightly ungraceful way (viz. `debug netmap`), stop logging
these broken pipe errors as far as possible. This will help avoid
confounding users when they scan backend logs.

Updates #18477

Signed-off-by: Amal Bansode <amal@tailscale.com>
This commit is contained in:
Amal Bansode
2026-01-26 16:41:03 -08:00
committed by GitHub
parent 9385dfe7f6
commit 6de5b01e04
5 changed files with 83 additions and 2 deletions
+4 -1
View File
@@ -35,6 +35,7 @@ import (
"tailscale.com/ipn/ipnlocal"
"tailscale.com/ipn/ipnstate"
"tailscale.com/logtail"
"tailscale.com/net/neterror"
"tailscale.com/net/netns"
"tailscale.com/net/netutil"
"tailscale.com/tailcfg"
@@ -913,7 +914,9 @@ func (h *Handler) serveWatchIPNBus(w http.ResponseWriter, r *http.Request) {
h.b.WatchNotificationsAs(ctx, h.Actor, mask, f.Flush, func(roNotify *ipn.Notify) (keepGoing bool) {
err := enc.Encode(roNotify)
if err != nil {
h.logf("json.Encode: %v", err)
if !neterror.IsClosedPipeError(err) {
h.logf("json.Encode: %v", err)
}
return false
}
f.Flush()