cloudflare/cloudflared · error

Unable to reach the origin service. The service may be down

Error message

Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared

What it means

proxyHTTPRequest in proxy/proxy.go wraps any error returned by the origin HTTP transport's RoundTrip with this message. It means cloudflared could not get any HTTP response at all from the local origin service — the connection failed before a response arrived. Note the wrapper first checks the request context: if the incoming request was cancelled by the client, the error is rewrapped as 'Incoming request ended abruptly' instead.

Source

Thrown at proxy/proxy.go:226

			}
		}
		// Request origin to keep connection alive to improve performance
		roundTripReq.Header.Set("Connection", "keep-alive")
	}

	// Set the User-Agent as an empty string if not provided to avoid inserting golang default UA
	if roundTripReq.Header.Get("User-Agent") == "" {
		roundTripReq.Header.Set("User-Agent", "")
	}

	_, ttfbSpan := tr.Tracer().Start(tr.Context(), "ttfb_origin")
	resp, err := httpService.RoundTrip(roundTripReq)
	if err != nil {
		tracing.EndWithErrorStatus(ttfbSpan, err)
		if err := roundTripReq.Context().Err(); err != nil {
			return errors.Wrap(err, "Incoming request ended abruptly")
		}
		return errors.Wrap(err, "Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared")
	}

	tracing.EndWithStatusCode(ttfbSpan, resp.StatusCode)
	defer func() { _ = resp.Body.Close() }()

	headers := make(http.Header, len(resp.Header))
	// copy headers
	for k, v := range resp.Header {
		headers[k] = v
	}

	// Add spans to response header (if available)
	tr.AddSpans(headers)

	err = w.WriteRespHeaders(resp.StatusCode, headers)
	if err != nil {
		return errors.Wrap(err, "Error writing response header")
	}

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Verify the origin service is running: curl the configured service URL directly from the machine running cloudflared (e.g. curl -v http://localhost:8080).
  2. Check the ingress/service URL in the tunnel config matches the actual origin port and scheme (http vs https).
  3. Inspect the wrapped cause (errors.Wrap preserves the original error) — connection refused vs timeout vs TLS error points to different fixes.
  4. If the origin uses HTTPS with a self-signed cert, configure originRequest settings (noTLSVerify / caPool) rather than switching to http.
  5. Check firewall/SELinux rules blocking cloudflared's loopback connections to the origin.

Example fix

// config.yaml before
ingress:
  - service: http://localhost:8080
// after (origin actually listens on 3000)
ingress:
  - service: http://localhost:3000
Defensive patterns

Strategy: validation

Validate before calling

// before serving traffic, verify the origin responds
resp, err := http.Get("http://localhost:8080/healthz")
if err != nil {
    log.Fatalf("origin service unreachable: %v", err)
}
resp.Body.Close()

Try / catch

if errors.Is(err, context.Canceled) || req.Context().Err() != nil {
    // client cancelled; treat as 'Incoming request ended abruptly'
    return
}
// otherwise inspect wrapped cause: connection refused vs timeout vs TLS
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
    // retry with backoff
}

Prevention

When it happens

Trigger: httpService.RoundTrip(roundTripReq) returns a non-nil error (dial failure, TLS failure, timeout, connection reset) while serving a request proxied through ProxyHTTP, and the request context is still alive.

Common situations: Origin web server is not running or listening on a different port than the tunnel config's service URL (e.g. http://localhost:8080 but app listens on 3000); origin crashed mid-deployment; firewall or SELinux blocking loopback; origin refusing plain HTTP where HTTPS is required (scheme mismatch).

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


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