{"record":{"id":"f0b6b9ae81d958f6","repo":"ginuerzh/gost","slug":"connection-queue-is-full","errorCode":null,"errorMessage":"connection queue is full","messagePattern":"connection queue is full","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"dns.go","lineNumber":229,"sourceCode":"\t}()\n\n\tselect {\n\tcase err := <-ln.errc:\n\t\treturn nil, err\n\tdefault:\n\t}\n\n\treturn ln, nil\n}\n\nfunc (l *dnsListener) serve(w dnsResponseWriter, mq []byte) (err error) {\n\tconn := newDNSServerConn(l.addr, w.RemoteAddr())\n\tconn.mq <- mq\n\n\tselect {\n\tcase l.connChan <- conn:\n\tdefault:\n\t\treturn errors.New(\"connection queue is full\")\n\t}\n\n\tselect {\n\tcase mr := <-conn.mr:\n\t\t_, err = w.Write(mr)\n\tcase <-conn.cclose:\n\t\terr = io.EOF\n\t}\n\treturn\n}\n\nfunc (l *dnsListener) ServeDNS(w dns.ResponseWriter, m *dns.Msg) {\n\tb, err := m.Pack()\n\tif err != nil {\n\t\tlog.Logf(\"[dns] %s: %v\", l.addr, err)\n\t\treturn\n\t}\n\tif err := l.serve(w, b); err != nil {","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/ginuerzh/gost/blob/a33fdbf4c98034f4bfeeaea9868909822b9c526d/dns.go#L211-L247","documentation":"The DNS-over-UDP server emulation in serve() creates a virtual connection and pushes it onto the listener's connChan; if the listener's backlog of unaccepted DNS 'connections' is full (non-blocking send), it rejects the new request with this error. It signals the server is accepting requests faster than the application's ServeDNS handler consumes them.","triggerScenarios":"Calling ServeDNS/ServeHTTP for a DNS request when the DNSListener's connChan (capacity-limited accept queue) is already full — i.e., the caller of Accept() is not draining incoming DNS queries fast enough.","commonSituations":"A DNS tunnel server whose Accept loop is blocked or slow (downstream handler stalled), traffic spikes from DNS tunneling clients, or forgetting to start the Accept loop at all.","solutions":["Ensure a concurrent Accept loop is running and processing connections promptly","Increase accept queue capacity or spawn more handler goroutines","Log and drop the request gracefully on this error (client will retry the query)","Profile the handler behind Accept for blocking calls (network, locks)"],"exampleFix":"// before\nconn.mq <- mq\nselect {\ncase l.connChan <- conn:\ndefault:\n    return errors.New(\"connection queue is full\")\n}\n// after\nselect {\ncase l.connChan <- conn:\ndefault:\n    log.Logf(\"[dns] accept queue full, dropping query from %s\", w.RemoteAddr())\n    return errors.New(\"connection queue is full\") // caller drops; consider resizing queue\n}","handlingStrategy":"try-catch","validationCode":"// cannot be pre-validated; concurrency/backpressure issue at accept time\nif queueDepth(l.connChan) >= cap(l.connChan) {\n    return fmt.Errorf(\"dns accept queue near capacity: %d/%d\", queueDepth(l.connChan), cap(l.connChan))\n}","typeGuard":null,"tryCatchPattern":"if err := serve(w, r); err != nil {\n    if err.Error() == \"connection queue is full\" {\n        // drop query; DNS client will retry — optionally backpressure metric here\n        return\n    }\n    log.Log(err)\n}","preventionTips":["Always run a dedicated Accept loop for the DNS listener before serving","Keep the ServeDNS/ServeHTTP handler non-blocking; offload heavy work to goroutines","Monitor queue depth and scale consumers under tunneling load spikes","Consider resizing the connChan buffer if sustained overflow is observed"],"tags":["dns","go","backpressure","queue-full"],"backgroundTag":"accept-queue-overflow","analyzedSha":"a33fdbf4c98034f4bfeeaea9868909822b9c526d","analyzedAt":"2026-09-02T22:15:54.506Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}