cloudflare/cloudflared · error

Currently Cloudflare Tunnel does not support %s protocol.

Error message

Currently Cloudflare Tunnel does not support %s protocol.

What it means

validateScheme checks the URL's scheme against cloudflared's supported protocol list (http, https, rdp, ssh, smb, tcp). Any other scheme — file, ftp, ws, wss, mailto, etc. — is rejected with this error. This is a deliberate restriction: Cloudflare Tunnel can only proxy these protocols.

Source

Thrown at validation/validation.go:155

			hostname, err = ValidateHostname(host)
			if err != nil {
				return "", fmt.Errorf("URL %s has invalid format", originUrl)
			}
			// This is why the path is preserved when `originUrl` doesn't have a schema.
			// Using `parsedUrl.Port()` here, instead of `port`, would remove the path
			return fmt.Sprintf("%s://%s", defaultScheme, net.JoinHostPort(hostname, port)), nil
		}
	}

}

func validateScheme(scheme string) error {
	for _, protocol := range supportedProtocols {
		if scheme == protocol {
			return nil
		}
	}
	return fmt.Errorf("Currently Cloudflare Tunnel does not support %s protocol.", scheme)
}

func validateIP(scheme, host, port string) (string, error) {
	if scheme == "" {
		scheme = defaultScheme
	}
	if port != "" {
		return fmt.Sprintf("%s://%s", scheme, net.JoinHostPort(host, port)), nil
	} else if strings.Contains(host, ":") {
		// IPv6
		return fmt.Sprintf("%s://[%s]", scheme, host), nil
	}
	return fmt.Sprintf("%s://%s", scheme, host), nil
}

// Access checks if a JWT from Cloudflare Access is valid.
type Access struct {
	verifier *oidc.IDTokenVerifier

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Switch the origin to a supported scheme: http, https, rdp, ssh, smb, or tcp
  2. For raw TCP/WebSocket services, use 'tcp' (or 'ws' semantics over http) as the scheme in config
  3. Fix typos in the scheme (htp → http)
  4. If the service runs on plain HTTP, simply omit the scheme and let the default http:// apply

Example fix

// before
ValidateUrl("ftp://files.example.com") // unsupported protocol
// after
ValidateUrl("tcp://files.example.com:21")
Defensive patterns

Strategy: validation

Validate before calling

var supported = map[string]bool{"http":true,"https":true,"rdp":true,"ssh":true,"smb":true,"tcp":true}
func schemeSupported(raw string) bool {
    u, err := url.Parse(raw)
    return err == nil && (u.Scheme == "" || supported[strings.ToLower(u.Scheme)])
}

Try / catch

if _, err := validation.ValidateUrl(origin); err != nil {
    if strings.Contains(err.Error(), "does not support") {
        return fmt.Errorf("origin %q uses an unsupported scheme; use http/https/rdp/ssh/smb/tcp", origin)
    }
}

Prevention

When it happens

Trigger: ValidateUrl('ftp://example.com'), 'ws://...', 'file:///path', or any URL where the text before '://' is not in the supported list. Also fires via NewAccessValidator if the domain/issuer uses an unsupported scheme.

Common situations: Users assuming websocket (ws://) or ftp URLs work as tunnel origins, copy-pasting browser URLs with unsupported schemes, or typos like 'htp://'.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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