<div dir="ltr"># HG changeset patch<br># User Zhefeng Chen <<a href="mailto:logchen2009@gmail.com" target="_blank">logchen2009@gmail.com</a>><br># Date 1761731339 -28800<br>#      Wed Oct 29 17:48:59 2025 +0800<br># Node ID b81b918263d445c32cb2cff5e2724e3cac62dab3<br># Parent  c3be8460587196f376bccf29817c3a6523e18150<br>Upstream: max_fails doesn't respect the next_upstream config<br><br>In the description of `max_fails`, it says:<br>What is considered an unsuccessful attempt is defined by the<br>`proxy_next_upstream`, `fastcgi_next_upstreami`,<br>`uwsgi_next_upstream`, `scgi_next_upstream`,<br>`memcached_next_upstream`, and `grpc_next_upstream` directives.<br><br>But actually 403 and 404 are always considered an successful<br>attempt, while other cases are always considered an<br>unsuccessful attempt.<br><br>The `ngx_http_upstream_free_round_robin_peer` function depends<br>on this to update the health check state.<br><br>diff -r c3be84605871 -r b81b918263d4 src/http/ngx_http_upstream.c<br>--- a/src/http/ngx_http_upstream.c      Tue Jul 15 22:22:53 2025 +0400<br>+++ b/src/http/ngx_http_upstream.c      Wed Oct 29 17:48:59 2025 +0800<br>@@ -4553,13 +4553,12 @@<br>             u->state->bytes_sent = u->peer.connection->sent;<br>         }<br><br>-        if (ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_403<br>-            || ft_type == NGX_HTTP_UPSTREAM_FT_HTTP_404)<br>+        if ((u->conf->next_upstream & ft_type) == ft_type)<br>         {<br>-            state = NGX_PEER_NEXT;<br>+            state = NGX_PEER_FAILED;<br><br>         } else {<br>-            state = NGX_PEER_FAILED;<br>+            state = NGX_PEER_NEXT;<br>         }<br><br>         u->peer.free(&u->peer, u->peer.data, state);<br></div>