@@ -357,7 +357,7 @@ func (h *Handler) Provision(ctx caddy.Context) error {
357
357
// set defaults on passive health checks, if necessary
358
358
if h .HealthChecks .Passive != nil {
359
359
h .HealthChecks .Passive .logger = h .logger .Named ("health_checker.passive" )
360
- if h .HealthChecks .Passive .FailDuration > 0 && h . HealthChecks . Passive . MaxFails == 0 {
360
+ if h .HealthChecks .Passive .MaxFails == 0 {
361
361
h .HealthChecks .Passive .MaxFails = 1
362
362
}
363
363
}
@@ -480,7 +480,7 @@ func (h *Handler) proxyLoopIteration(r *http.Request, origReq *http.Request, w h
480
480
upstream := h .LoadBalancing .SelectionPolicy .Select (upstreams , r , w )
481
481
if upstream == nil {
482
482
if proxyErr == nil {
483
- proxyErr = caddyhttp .Error (http .StatusServiceUnavailable , fmt . Errorf ( "no upstreams available" ) )
483
+ proxyErr = caddyhttp .Error (http .StatusServiceUnavailable , noUpstreamsAvailable )
484
484
}
485
485
if ! h .LoadBalancing .tryAgain (h .ctx , start , retries , proxyErr , r ) {
486
486
return true , proxyErr
@@ -1010,17 +1010,23 @@ func (lb LoadBalancing) tryAgain(ctx caddy.Context, start time.Time, retries int
1010
1010
// should be safe to retry, since without a connection, no
1011
1011
// HTTP request can be transmitted; but if the error is not
1012
1012
// specifically a dialer error, we need to be careful
1013
- if _ , ok := proxyErr .(DialError ); proxyErr != nil && ! ok {
1013
+ if proxyErr != nil {
1014
+ _ , isDialError := proxyErr .(DialError )
1015
+ herr , isHandlerError := proxyErr .(caddyhttp.HandlerError )
1016
+
1014
1017
// if the error occurred after a connection was established,
1015
1018
// we have to assume the upstream received the request, and
1016
1019
// retries need to be carefully decided, because some requests
1017
1020
// are not idempotent
1018
- if lb .RetryMatch == nil && req .Method != "GET" {
1019
- // by default, don't retry requests if they aren't GET
1020
- return false
1021
- }
1022
- if ! lb .RetryMatch .AnyMatch (req ) {
1023
- return false
1021
+ if ! isDialError && ! (isHandlerError && errors .Is (herr , noUpstreamsAvailable )) {
1022
+ if lb .RetryMatch == nil && req .Method != "GET" {
1023
+ // by default, don't retry requests if they aren't GET
1024
+ return false
1025
+ }
1026
+
1027
+ if ! lb .RetryMatch .AnyMatch (req ) {
1028
+ return false
1029
+ }
1024
1030
}
1025
1031
}
1026
1032
@@ -1421,6 +1427,8 @@ func (c ignoreClientGoneContext) Err() error {
1421
1427
// from the proxy handler.
1422
1428
const proxyHandleResponseContextCtxKey caddy.CtxKey = "reverse_proxy_handle_response_context"
1423
1429
1430
+ var noUpstreamsAvailable = fmt .Errorf ("no upstreams available" )
1431
+
1424
1432
// Interface guards
1425
1433
var (
1426
1434
_ caddy.Provisioner = (* Handler )(nil )
0 commit comments