ginuerzh/gost · error
accpet on closed listener
Error message
accpet on closed listener
What it means
quicListener.Accept returns this error when the listener's error channel is closed, meaning the underlying QUIC listener has been shut down. The channel-closed signal is converted into an explicit error so callers can distinguish 'listener closed' from a real accept failure.
Source
Thrown at quic.go:239
}
cc := &quicConn{Stream: stream, laddr: session.LocalAddr(), raddr: session.RemoteAddr()}
select {
case l.connChan <- cc:
default:
cc.Close()
log.Logf("[quic] %s - %s: connection queue is full", session.RemoteAddr(), session.LocalAddr())
}
}
}
func (l *quicListener) Accept() (conn net.Conn, err error) {
var ok bool
select {
case conn = <-l.connChan:
case err, ok = <-l.errChan:
if !ok {
err = errors.New("accpet on closed listener")
}
}
return
}
func (l *quicListener) Addr() net.Addr {
return l.ln.Addr()
}
func (l *quicListener) Close() error {
return l.ln.Close()
}
type quicConn struct {
quic.Stream
laddr net.Addr
raddr net.Addr
}View on GitHub (pinned to a33fdbf4c9)
Solutions
- Stop the Accept loop when this error is returned (standard pattern: return from the accept goroutine)
- Ensure Close() is only called once and that shutdown logic terminates accept loops
- If you didn't intend to close, find what closed the listener (supervisor, signal handler, parent context)
Example fix
// before
for {
conn, err := l.Accept()
if err != nil { log.Log(err); continue } // infinite loop on closed listener
go handle(conn)
}
// after
for {
conn, err := l.Accept()
if err != nil { return } // stop looping when listener is closed
go handle(conn)
} Defensive patterns
Strategy: try-catch
Try / catch
conn, err := l.Accept()
if err != nil {
// listener closed or fatal accept error: stop the accept loop
return
} Prevention
- Terminate accept goroutines on listener Close
- Ensure Close is idempotent and coordinated with accept loops
- Track listener lifecycle with a done channel/context
When it happens
Trigger: Calling Accept on a quicListener after Close() has been invoked (which closes l.errChan), so the select receives the zero error with ok == false.
Common situations: Accept loops that keep running after the server was shut down; a race between Close() and a pending/next Accept call in a connection-handling goroutine.
Related errors
- closed
- accpet on closed listener
- ciphertext too short
- accpet on closed listener
- accept on closed listener
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/80fbcbda7d1937c8.
Report an issue: GitHub.