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.mView on GitHub (pinned to c96f600972)
Solutions
- Change the URI to http:// or https://
- For websockets/TCP use the appropriate library (websocket, net.Dial) instead of fasthttp.Client
- Validate the scheme from config before constructing the request (req.URI().SetScheme or string check)
- 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
- Normalize base URLs at startup: default to https, reject others
- Route ws:// / ftp:// traffic to the correct client library
- Validate scheme variables from config once, not per request
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
- invalid host %q: use a host client for multiple hosts
- must implement readat
- directory index required
- no 'create file' permissions
- seek is not implemented
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/32f7afb495dcf12d.
Report an issue: GitHub.