ginuerzh/gost · info · net.OpError

deadline not supported

Error message

deadline not supported

What it means

nopConn.SetDeadline always returns a *net.OpError with Err 'deadline not supported'. Since the nop connection performs no I/O and blocks forever on nothing, deadlines have no meaning and the library rejects them. The error is deterministic: every call fails regardless of the time value passed.

Source

Thrown at gost.go:179

func (c *nopConn) Write(b []byte) (n int, err error) {
	return 0, &net.OpError{Op: "write", Net: "nop", Source: nil, Addr: nil, Err: errors.New("write not supported")}
}

func (c *nopConn) Close() error {
	return nil
}

func (c *nopConn) LocalAddr() net.Addr {
	return nil
}

func (c *nopConn) RemoteAddr() net.Addr {
	return nil
}

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

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

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

// splitLine splits a line text by white space, mainly used by config parser.
func splitLine(line string) []string {
	if line == "" {
		return nil
	}
	if n := strings.IndexByte(line, '#'); n >= 0 {
		line = line[:n]
	}

View on GitHub (pinned to a33fdbf4c9)

Solutions

  1. Skip deadline configuration for nop connections (type-check or flag placeholder conns)
  2. Ignore this specific error: check for the *net.OpError with Err 'deadline not supported' and treat as no-op
  3. Use a real connection type if deadlines must be enforced — nopConn cannot honor them
  4. Wrap nopConn in an adapter that implements deadline setters as no-ops if your framework requires success

Example fix

// before
if err := conn.SetDeadline(time.Now().Add(30*time.Second)); err != nil { return err }
// after
if err := conn.SetDeadline(time.Now().Add(30*time.Second)); err != nil {
  var opErr *net.OpError
  if errors.As(err, &opErr) && opErr.Err.Error() == "deadline not supported" {
    return nil // placeholder conn, deadlines unsupported
  }
  return err
}
Defensive patterns

Strategy: validation

Validate before calling

if fmt.Sprintf("%T", conn) == "*gost.nopConn" {
    return nil // skip deadline: unsupported on nop connections
}

Type guard

func supportsDeadlines(c net.Conn) bool {
    return fmt.Sprintf("%T", c) != "*gost.nopConn"
}

Try / catch

if err := conn.SetDeadline(t); err != nil {
    var oe *net.OpError
    if errors.As(err, &oe) && oe.Err.Error() == "deadline not supported" {
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: Calling SetDeadline(t) on a *nopConn — typically from a timeout wrapper (net.Conn deadline scaffolding, heartbeat/idle timers) applied uniformly to all connections including placeholders.

Common situations: Generic connection wrappers that set deadlines on every conn they touch; code paths where a discarded/placeholder connection leaks into deadline-setting logic; tests exercising timeout handling against a nopConn.

Related errors


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