ginuerzh/gost · warning · net.OpError

deadline not supported

Error message

deadline not supported

What it means

tunTapConn.SetDeadline always returns a *net.OpError wrapping 'deadline not supported'. The TUN/TAP connection is backed by an os-level device file whose read/write loops do not support deadlines, so the interface method is implemented to explicitly reject deadline calls.

Source

Thrown at tuntap.go:801

func (c *tunTapConn) Write(b []byte) (n int, err error) {
	return c.ifce.Write(b)
}

func (c *tunTapConn) Close() (err error) {
	return c.ifce.Close()
}

func (c *tunTapConn) LocalAddr() net.Addr {
	return c.addr
}

func (c *tunTapConn) RemoteAddr() net.Addr {
	return &net.IPAddr{}
}

func (c *tunTapConn) SetDeadline(t time.Time) error {
	return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}

func (c *tunTapConn) SetReadDeadline(t time.Time) error {
	return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}

func (c *tunTapConn) SetWriteDeadline(t time.Time) error {
	return &net.OpError{Op: "set", Net: "tuntap", Source: nil, Addr: nil, Err: errors.New("deadline not supported")}
}

// IsIPv6Multicast reports whether the address addr is an IPv6 multicast address.
func IsIPv6Multicast(addr net.HardwareAddr) bool {
	return addr[0] == 0x33 && addr[1] == 0x33
}

View on GitHub (pinned to a33fdbf4c9)

Solutions

  1. Do not set deadlines on tunTapConn; rely on context/cancellation around the copy loops instead.
  2. Wrap the conn so deadline calls become no-ops: define SetDeadline/SetReadDeadline/SetWriteDeadline to return nil.
  3. Detect this error (net.OpError with Err 'deadline not supported') and treat it as non-fatal in generic net.Conn handling code.

Example fix

// before
conn.SetDeadline(time.Now().Add(5 * time.Second)) // returns OpError
// after
type noDeadlineConn struct{ net.Conn }
func (c noDeadlineConn) SetDeadline(t time.Time) error      { return nil }
func (c noDeadlineConn) SetReadDeadline(t time.Time) error  { return nil }
func (c noDeadlineConn) SetWriteDeadline(t time.Time) error { return nil }
Defensive patterns

Strategy: fallback

Type guard

func supportsDeadlines(c net.Conn) bool {
    type d interface{ SetDeadline(time.Time) error }
    _, ok := c.(d)
    return ok
}
// Note: tunTapConn implements SetDeadline but always errors; treat it specially.

Try / catch

if err := conn.SetDeadline(time.Now().Add(timeout)); err != nil {
    var opErr *net.OpError
    if errors.As(err, &opErr) && opErr.Err.Error() == "deadline not supported" {
        // fall back to timer + Close based timeout
    }
}

Prevention

When it happens

Trigger: Calling SetDeadline on a tunTapConn — e.g. wrapping the TUN/TAP conn in code that calls net.Conn deadline methods (custom timeouts, io copy helpers like SetDeadline before Read/Write, or libraries such as TLS handshake timeouts).

Common situations: Using the TAP/TUN conn as a drop-in net.Conn inside a library that sets deadlines unconditionally (crypto/tls, QUIC, HTTP clients); writing generic connection wrappers that call SetDeadline on every conn they handle.

Related errors


AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02). Data as JSON: /api/errors/16a552e1eafa0387. Report an issue: GitHub.