[nginx] Mail: fixed occasional mail proxy errors on Windows.

Maxim Dounin mdounin at mdounin.ru
Thu Mar 26 04:02:24 UTC 2026


details:   http://freenginx.org/hg/nginx/rev/04172e7f25c6
branches:  
changeset: 9491:04172e7f25c6
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Thu Mar 26 06:51:59 2026 +0300
description:
Mail: fixed occasional mail proxy errors on Windows.

On Windows, in some cases a read event is reported by select() before a
write event signals that a connection to a backend server is established.
This results in c->write->ready not being set when the read handler is
called, and subsequent c->send() returns NGX_AGAIN, as ngx_wsasend()
does not do anything unless c->write->ready is set.  And the connection
establishment code assumes that short initial commands can be sent
without blocking, further resulting in an internal error being reported
to the client.

It is not clear why this happens, though it was observed in practice when
running tests on Windows 10 (22H2).

The fix is to block read handlers from doing anything unless c->write->ready
is set, much like we do when sending the PROXY protocol header.

diffstat:

 src/mail/ngx_mail_proxy_module.c |  6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diffs (30 lines):

diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c
--- a/src/mail/ngx_mail_proxy_module.c
+++ b/src/mail/ngx_mail_proxy_module.c
@@ -248,7 +248,7 @@ ngx_mail_proxy_pop3_handler(ngx_event_t 
         return;
     }
 
-    if (s->proxy->proxy_protocol) {
+    if (s->proxy->proxy_protocol || !c->write->ready) {
         ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail proxy pop3 busy");
 
         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
@@ -398,7 +398,7 @@ ngx_mail_proxy_imap_handler(ngx_event_t 
         return;
     }
 
-    if (s->proxy->proxy_protocol) {
+    if (s->proxy->proxy_protocol || !c->write->ready) {
         ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail proxy imap busy");
 
         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
@@ -571,7 +571,7 @@ ngx_mail_proxy_smtp_handler(ngx_event_t 
         return;
     }
 
-    if (s->proxy->proxy_protocol) {
+    if (s->proxy->proxy_protocol || !c->write->ready) {
         ngx_log_debug0(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail proxy smtp busy");
 
         if (ngx_handle_read_event(c->read, 0) != NGX_OK) {


More information about the nginx-devel mailing list