@@ -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
@@ -1016,17 +1016,23 @@ func (lb LoadBalancing) tryAgain(ctx caddy.Context, start time.Time, retries int
1016
1016
// should be safe to retry, since without a connection, no
1017
1017
// HTTP request can be transmitted; but if the error is not
1018
1018
// specifically a dialer error, we need to be careful
1019
- if _ , ok := proxyErr .(DialError ); proxyErr != nil && ! ok {
1019
+ if proxyErr != nil {
1020
+ _ , isDialError := proxyErr .(DialError )
1021
+ herr , isHandlerError := proxyErr .(caddyhttp.HandlerError )
1022
+
1020
1023
// if the error occurred after a connection was established,
1021
1024
// we have to assume the upstream received the request, and
1022
1025
// retries need to be carefully decided, because some requests
1023
1026
// are not idempotent
1024
- if lb .RetryMatch == nil && req .Method != "GET" {
1025
- // by default, don't retry requests if they aren't GET
1026
- return false
1027
- }
1028
- if ! lb .RetryMatch .AnyMatch (req ) {
1029
- return false
1027
+ if ! isDialError && ! (isHandlerError && errors .Is (herr , noUpstreamsAvailable )) {
1028
+ if lb .RetryMatch == nil && req .Method != "GET" {
1029
+ // by default, don't retry requests if they aren't GET
1030
+ return false
1031
+ }
1032
+
1033
+ if ! lb .RetryMatch .AnyMatch (req ) {
1034
+ return false
1035
+ }
1030
1036
}
1031
1037
}
1032
1038
@@ -1427,6 +1433,8 @@ func (c ignoreClientGoneContext) Err() error {
1427
1433
// from the proxy handler.
1428
1434
const proxyHandleResponseContextCtxKey caddy.CtxKey = "reverse_proxy_handle_response_context"
1429
1435
1436
+ var noUpstreamsAvailable = fmt .Errorf ("no upstreams available" )
1437
+
1430
1438
// Interface guards
1431
1439
var (
1432
1440
_ caddy.Provisioner = (* Handler )(nil )
0 commit comments