ginuerzh/gost · error · net.OpError
write not supported
Error message
write not supported
What it means
nopConn.Write always fails with a *net.OpError whose Err is 'write not supported'. The nop connection is a pure placeholder that performs no I/O, so writes (like reads) are rejected. It exists only to satisfy the net.Conn interface for discarded/placeholder traffic paths.
Source
Thrown at gost.go:163
return rw.r.Read(p)
}
func (rw *readWriter) Write(p []byte) (n int, err error) {
return rw.w.Write(p)
}
var nopClientConn = &nopConn{}
// a nop connection implements net.Conn,
// it does nothing.
type nopConn struct{}
func (c *nopConn) Read(b []byte) (n int, err error) {
return 0, &net.OpError{Op: "read", Net: "nop", Source: nil, Addr: nil, Err: errors.New("read not supported")}
}
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")}
}
View on GitHub (pinned to a33fdbf4c9)
Solutions
- Don't write to nopConn — use it only where traffic should be dropped silently and discard the data yourself (io.Copy(io.Discard, src))
- If a writable sink is needed, use io.Discard via an adapter or a net.Pipe() endpoint
- Match on the *net.OpError Err ('write not supported') and treat as intentional discard
- Change nopConn (if in your fork) to return len(b), nil for silent drop semantics
Example fix
// before io.Copy(nop, src) // errors: write not supported // after io.Copy(io.Discard, src) // intentionally drop the traffic
Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := conn.(*gostNopConn); ok {
// discard instead of writing to nopConn
io.Copy(io.Discard, src)
return nil
} Type guard
func isNopConn(c net.Conn) bool {
return fmt.Sprintf("%T", c) == "*gost.nopConn"
} Try / catch
_, err := conn.Write(data)
if err != nil {
var oe *net.OpError
if errors.As(err, &oe) && oe.Err.Error() == "write not supported" {
return len(data), nil // treat as intentional discard
}
return err
} Prevention
- Route drop-traffic through io.Discard, not nopConn writes
- Don't wire nopConn into two-way relay pairs as a destination
- Type-check placeholder conns before generic write paths
When it happens
Trigger: Any call to Write(b []byte) on a *nopConn, e.g. relaying data toward a connection that was replaced by a nopConn (traffic being discarded, bypassed hop, or test stub).
Common situations: io.Copy(dst, src) where dst is a nopConn in a two-way relay; sending responses through a discarded connection; tests writing into the stub.
Related errors
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/0fffe5823ae221b9.
Report an issue: GitHub.