valyala/fasthttp · error

unsupported protocol %q. http and https are supported

Error message

unsupported protocol %q. http and https are supported

What it means

fasthttp's generic Client only supports http and https URI schemes when dispatching to HostClients. Any other scheme in the request URI causes this error before any connection is attempted.

Source

Thrown at client.go:557

// It is recommended obtaining req and resp via AcquireRequest
// and AcquireResponse in performance-critical code.
func (c *Client) Do(req *Request, resp *Response) error {
	uri := req.URI()
	if uri == nil {
		return ErrorInvalidURI
	}

	host := uri.Host()

	if bytes.ContainsRune(host, ',') {
		return fmt.Errorf("invalid host %q: use a host client for multiple hosts", host)
	}

	isTLS := false
	if uri.isHTTPS() {
		isTLS = true
	} else if !uri.isHTTP() {
		return fmt.Errorf("unsupported protocol %q. http and https are supported", uri.Scheme())
	}

	c.mOnce.Do(func() {
		c.m = make(map[string]*HostClient)
		c.ms = make(map[string]*HostClient)
	})
	hc, err := c.hostClient(host, isTLS)
	if err != nil {
		return err
	}

	atomic.AddInt32(&hc.pendingClientRequests, 1)
	defer atomic.AddInt32(&hc.pendingClientRequests, -1)
	return hc.Do(req, resp)
}

func (c *Client) hostClient(host []byte, isTLS bool) (*HostClient, error) {
	m := c.m

View on GitHub (pinned to c96f600972)

Solutions

  1. Change the URI to http:// or https://
  2. For websockets/TCP use the appropriate library (websocket, net.Dial) instead of fasthttp.Client
  3. Validate the scheme from config before constructing the request (req.URI().SetScheme or string check)
  4. Normalize the base URL at startup: default missing schemes to http and reject unknown ones

Example fix

// before
req.SetRequestURI(baseURL + "/path") // baseURL = "ftp://example.com"
client.Do(req, resp)
// after
if !strings.HasPrefix(baseURL, "http://") && !strings.HasPrefix(baseURL, "https://") {
    return fmt.Errorf("unsupported base URL scheme: %q", baseURL)
}
req.SetRequestURI(baseURL + "/path")
Defensive patterns

Strategy: validation

Validate before calling

if !strings.HasPrefix(baseURL, "http://") && !strings.HasPrefix(baseURL, "https://") {
    return fmt.Errorf("scheme must be http or https: %q", baseURL)
}

Type guard

func isHTTPScheme(u string) bool {
    pu, err := url.Parse(u)
    return err == nil && (pu.Scheme == "http" || pu.Scheme == "https")
}

Try / catch

err := client.Do(req, resp)
if err != nil {
    if strings.Contains(err.Error(), "unsupported protocol") {
        return fmt.Errorf("bad scheme in config: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: client.Do with a URI whose scheme is not http/https: "ftp://...", "ws://...", missing scheme handled incorrectly, or a URI built with a scheme variable set from config.

Common situations: Config-driven base URLs where users enter ws:// or no scheme, switching between grpc/websocket endpoints in shared HTTP code, typos like htp://.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/32f7afb495dcf12d. Report an issue: GitHub.