cloudflare/cloudflared · error

error while processing middleware handler %s

Error message

error while processing middleware handler %s

What it means

applyIngressMiddleware runs each middleware handler attached to the matched ingress rule (e.g. access, rate-limit handlers). If handler.Handle returns an error it is wrapped with the handler's name so the operator knows which middleware rejected the request. A bool also indicates the request should be filtered.

Source

Thrown at proxy/proxy.go:67

	flowLimiter cfdflow.Limiter,
	log *zerolog.Logger,
) *Proxy {
	proxy := &Proxy{
		ingressRules: ingressRules,
		originDialer: originDialer,
		tags:         tags,
		flowLimiter:  flowLimiter,
		log:          log,
	}

	return proxy
}

func (p *Proxy) applyIngressMiddleware(rule *ingress.Rule, r *http.Request, w connection.ResponseWriter) (error, bool) {
	for _, handler := range rule.Handlers {
		result, err := handler.Handle(r.Context(), r)
		if err != nil {
			return errors.Wrap(err, fmt.Sprintf("error while processing middleware handler %s", handler.Name())), false
		}

		if result.ShouldFilterRequest {
			_ = w.WriteRespHeaders(result.StatusCode, nil)
			return fmt.Errorf("request filtered by middleware handler (%s) due to: %s", handler.Name(), result.Reason), true
		}
	}
	return nil, true
}

// ProxyHTTP further depends on ingress rules to establish a connection with the origin service. This may be
// a simple roundtrip or a tcp/websocket dial depending on ingres rule setup.
func (p *Proxy) ProxyHTTP(
	w connection.ResponseWriter,
	tr *tracing.TracedHTTPRequest,
	isWebsocket bool,
) error {
	incrementRequests()

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Note the handler name in the wrapped message and check that middleware's specific failure (the inner error).
  2. For Access handlers, ensure the client presents a valid Cloudflare Access token (cf_access_token / authenticated session).
  3. Verify the ingress rule's middleware configuration matches the Access application/audience tags.
  4. If the middleware is not wanted, remove it from the rule's configuration.

Example fix

// before (config.yml)
ingress:
  - hostname: app.example.com
    service: http://localhost:8080
    originRequest: {}
// after (keep Access, but ensure app is configured)
ingress:
  - hostname: app.example.com
    service: http://localhost:8080
# ensure Access application + token validation is set up in the Cloudflare dashboard
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify Access middleware prerequisites before routing:
// ensure the request carries an Access token when the rule has handlers
func requiresAccess(handlers []string) bool {
    for _, h := range handlers {
        if strings.Contains(strings.ToLower(h), "access") {
            return true
        }
    }
    return false
}

Try / catch

if err, filtered := p.applyIngressMiddleware(rule, r, w); err != nil || filtered {
    log.Warn().Err(err).Str("handler", rule.Handlers[0].Name()).Msg("middleware rejected request")
    return
}

Prevention

When it happens

Trigger: ProxyHTTP matches an ingress rule whose Handlers list contains a middleware whose Handle call errors — e.g. Cloudflare Access token validation failing, or a custom handler returning an error for the request.

Common situations: Access-protected routes where the request's JWT/Access token is invalid or expired, misconfigured Access application binding, or a custom middleware failing on malformed requests.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/029f711ea62fff19. Report an issue: GitHub.