valyala/fasthttp · error

unsupported http version %q

Error message

unsupported http version %q

What it means

When secure error logging is enabled, fasthttp reports an unsupported HTTP protocol version without echoing the raw response line. The protocol token from the status line failed isHTTPVersion (must look like HTTP/x.y). This is the privacy-preserving variant of error 139.

Source

Thrown at header.go:2874

		statusCode = b[:n]
		statusMessage = b[n+1:]
	}
	if len(statusCode) != 3 {
		if h.secureErrorLogMessage {
			return 0, ErrUnexpectedStatusCodeChar
		}
		return 0, fmt.Errorf("invalid response status code %q: response %q", statusCode, buf)
	}
	h.statusCode, n, err = parseUintBuf(statusCode)
	if err != nil || n != 3 {
		if h.secureErrorLogMessage {
			return 0, ErrUnexpectedStatusCodeChar
		}
		return 0, fmt.Errorf("invalid response status code %q: response %q", statusCode, buf)
	}
	if !isHTTPVersion(protoStr) {
		if h.secureErrorLogMessage {
			return 0, fmt.Errorf("unsupported http version %q", protoStr)
		}
		return 0, fmt.Errorf("unsupported http version %q in %q", protoStr, buf)
	}
	h.noHTTP11 = !bytes.Equal(protoStr, strHTTP11)
	h.protocol = append(h.protocol[:0], protoStr...)
	if len(statusMessage) > 0 {
		h.SetStatusMessage(statusMessage)
	}

	return len(buf) - len(bNext), nil
}

func isValidMethod(method []byte) bool {
	for _, ch := range method {
		if validMethodValueByteTable[ch] == 0 {
			return false
		}
	}

View on GitHub (pinned to c96f600972)

Solutions

  1. Fix the URL scheme/TLS configuration so the client talks to an actual HTTP endpoint
  2. Verify the upstream service speaks HTTP/1.x (not raw TLS, SPDY, or a custom protocol)
  3. Check proxies/load balancers for protocol mismatches (e.g. HTTPS listener forwarding to plaintext expectation)

Example fix

// before
var c fasthttp.Client
resp, err := c.Get(nil, "http://tls-only-host/")
// after
var c fasthttp.Client
resp, err := c.Get(nil, "https://tls-only-host/") // with TLSConfig set
Defensive patterns

Strategy: try-catch

Validate before calling

u, _ := url.Parse(endpoint)
if u.Scheme != "http" && u.Scheme != "https" {
    return fmt.Errorf("unsupported scheme %q", u.Scheme)
}

Type guard

func isUnsupportedVersionErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "unsupported http version")
}

Try / catch

if err := client.Do(req, resp); err != nil {
    var sue = strings.Contains(err.Error(), "unsupported http version")
    if sue {
        return fmt.Errorf("endpoint requires a different protocol/TLS: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: ResponseHeader.parseFirstLine with h.secureErrorLogMessage==true and a protoStr (e.g. 'HTTPS', 'FTP', binary junk) that is not an HTTP/1.x or valid HTTP version string.

Common situations: Same as the non-secure variant: TLS data sent to a plain-HTTP client, non-HTTP services, misconfigured proxies — but in production configs with SecureErrorLogMessage enabled.

Related errors


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