cloudflare/cloudflared · warning

error setting write deadline: %w

Error message

error setting write deadline: %w

What it means

The write-half counterpart in GorillaConn.SetDeadline: after the read deadline is set successfully, SetWriteDeadline on the underlying gorilla connection failed. Like the read variant, this typically means the connection is closed or broken; it wraps and returns the underlying error via %w.

Source

Thrown at websocket/connection.go:76

// Write will write messages to the websocket connection
func (c *GorillaConn) Write(p []byte) (int, error) {
	if err := c.Conn.WriteMessage(websocket.BinaryMessage, p); err != nil {
		return 0, err
	}

	return len(p), nil
}

// SetDeadline sets both read and write deadlines, as per net.Conn interface docs:
// "It is equivalent to calling both SetReadDeadline and SetWriteDeadline."
// Note there is no synchronization here, but the gorilla implementation isn't thread safe anyway
func (c *GorillaConn) SetDeadline(t time.Time) error {
	if err := c.Conn.SetReadDeadline(t); err != nil {
		return fmt.Errorf("error setting read deadline: %w", err)
	}
	if err := c.Conn.SetWriteDeadline(t); err != nil {
		return fmt.Errorf("error setting write deadline: %w", err)
	}
	return nil
}

type Conn struct {
	rw  io.ReadWriter
	log *zerolog.Logger
	// writeLock makes sure
	// 1. Only one write at a time. The pinger and Stream function can both call write.
	// 2. Close only returns after in progress Write is finished, and no more Write will succeed after calling Close.
	writeLock sync.Mutex
	done      bool
}

func NewConn(ctx context.Context, rw io.ReadWriter, log *zerolog.Logger) *Conn {
	c := &Conn{
		rw:  rw,
		log: log,

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Treat as connection-fatal: propagate the error and close/reconnect the websocket session
  2. Stop deadline-refresh timers when Close() is called to avoid racing teardown
  3. Filter net.ErrClosed / 'use of closed network connection' as expected during shutdown
  4. Check the underlying TCP connection health; a write-deadline failure usually means the socket is already dead

Example fix

// before
if err := conn.SetDeadline(t); err != nil {
    logger.Error().Err(err).Msg("set deadline")
}
// after — reconnect on any deadline-set failure
if err := conn.SetDeadline(t); err != nil {
    _ = conn.Close()
    return reconnect(ctx)
}
Defensive patterns

Strategy: try-catch

Try / catch

if err := conn.SetDeadline(t); err != nil {
    _ = conn.Close()
    return fmt.Errorf("websocket dead, reconnect: %w", err)
}

Prevention

When it happens

Trigger: SetDeadline called on a GorillaConn whose underlying connection is closed/half-broken; the read deadline succeeds but the write deadline call fails, common when the peer closed the socket between the two calls.

Common situations: Race between connection teardown and ping/pong keepalive loops that reset deadlines; abrupt peer disconnect mid-stream on websocket-proxied protocols (ssh/rdp over Access).

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/6d92a824e859e28a. Report an issue: GitHub.