cloudflare/cloudflared · error

unrecognized service: %s, %t

Error message

unrecognized service: %s, %t

What it means

Returned by Proxy.ProxyHTTP when the resolved ingress rule's service type does not match any service kind the proxy knows how to handle (httpstatuses, bastion, HTTPLocalProxy, etc.). It means the ingress rule's Service field parsed into a type ProxyHTTP cannot dispatch, and the error includes both the service string and whether an origin proxy was produced. This indicates a misconfiguration or an unhandled service type in the ingress rules.

Source

Thrown at proxy/proxy.go:139

		if err != nil {
			return err
		}
		flusher, ok := w.(http.Flusher)
		if !ok {
			return fmt.Errorf("response writer is not a flusher")
		}
		rws := connection.NewHTTPResponseReadWriterAcker(w, flusher, req)
		logger := logger.With().Str(logFieldDestAddr, dest).Logger()
		if err := p.proxyStream(tr.ToTracedContext(), rws, dest, originProxy, &logger); err != nil {
			logRequestError(&logger, err)
			return err
		}
		return nil
	case ingress.HTTPLocalProxy:
		p.proxyLocalRequest(originProxy, w, req, isWebsocket)
		return nil
	default:
		return fmt.Errorf("unrecognized service: %s, %t", rule.Service, originProxy)
	}
}

// ProxyTCP proxies to a TCP connection between the origin service and cloudflared.
func (p *Proxy) ProxyTCP(
	ctx context.Context,
	conn connection.ReadWriteAcker,
	req *connection.TCPRequest,
) error {
	incrementTCPRequests()
	defer decrementTCPConcurrentRequests()

	logger := newTCPLogger(p.log, req)

	// Try to start a new flow
	if err := p.flowLimiter.Acquire(management.TCP.String()); err != nil {
		logger.Warn().Msg("Too many concurrent flows being handled, rejecting tcp proxy")
		return errors.Wrap(err, "failed to start tcp flow due to rate limiting")

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Check the rule's service value in the error output and correct the scheme (http://, https://, http_status:, bastion, unix:, etc.)
  2. Validate the full config before running: cloudflared tunnel ingress validate
  3. Upgrade cloudflared if the service type comes from remote config newer than the binary
  4. For tests, construct rules only via ingress.ParseIngress so invalid service types are rejected early

Example fix

// before (config.yml)
ingress:
  - service: htp://localhost:8080
// after
ingress:
  - service: http://localhost:8080
Defensive patterns

Strategy: validation

Validate before calling

// Validate ingress rules before running the tunnel
// shell: cloudflared tunnel ingress validate
// Go: parse rules through the supported parser
rules, err := ingress.ParseIngress(rawConfig)
if err != nil {
    return fmt.Errorf("invalid ingress service: %w", err)
}
for _, r := range rules.Rules {
    if !supportedServiceSchemes[strings.SplitN(r.Service, ":", 2)[0]] {
        return fmt.Errorf("unsupported service: %s", r.Service)
    }
}

Try / catch

err := proxy.ProxyHTTP(ctx, w, r, rule, log)
if err != nil && strings.Contains(err.Error(), "unrecognized service") {
    log.Error().Str("service", rule.Service.String()).Msg("ingress rule service type not supported; check scheme and cloudflared version")
    http.Error(w, "misconfigured service", http.StatusBadGateway)
    return
}

Prevention

When it happens

Trigger: An ingress rule's service URL has a scheme cloudflared does not recognize or cannot resolve to an origin service (e.g. unsupported scheme, malformed service string that still parsed), so the type switch in ProxyHTTP falls into the default branch.

Common situations: Typos in the service scheme in config.yml (e.g. 'htp://' instead of 'http://', missing 'http_status:'); remote-config pushing a service type newer than the running cloudflared binary supports; tests exercising ProxyHTTP with a rule whose service was never validated by ingress parsing.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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