caddyserver/caddy · error

unsupported HTTP version: %s, supported version: %s

Error message

unsupported HTTP version: %s, supported version: %s

What it means

The HTTP transport's `versions` list is validated against `allowedVersions` (`"1.1"`, `"2"`, `"3"`). Any other string fails provisioning immediately (per issue #7111, Caddy errors instead of guessing), with the supported list included in the message.

Source

Thrown at modules/caddyhttp/reverseproxy/httptransport.go:193

}

var (
	allowedVersions       = []string{"1.1", "2", "h2c", "3"}
	allowedVersionsString = strings.Join(allowedVersions, ", ")
)

// Provision sets up h.Transport with a *http.Transport
// that is ready to use.
func (h *HTTPTransport) Provision(ctx caddy.Context) error {
	if len(h.Versions) == 0 {
		h.Versions = []string{"1.1", "2"}
	}
	// some users may provide http versions not recognized by caddy, instead of trying to
	// guess the version, we just error out and let the user fix their config
	// see: https://github.com/caddyserver/caddy/issues/7111
	for _, v := range h.Versions {
		if !slices.Contains(allowedVersions, v) {
			return fmt.Errorf("unsupported HTTP version: %s, supported version: %s", v, allowedVersionsString)
		}
	}

	rt, err := h.NewTransport(ctx)
	if err != nil {
		return err
	}
	h.Transport = rt

	return nil
}

// NewTransport builds a standard-lib-compatible http.Transport value from h.
func (h *HTTPTransport) NewTransport(caddyCtx caddy.Context) (*http.Transport, error) {
	// Set keep-alive defaults if it wasn't otherwise configured
	if h.KeepAlive == nil {
		h.KeepAlive = new(KeepAlive)
	}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Use only the exact strings from the message: "1.1", "2", "3"
  2. Replace bare "1" or "1.0" with "1.1"
  3. Remove multiple values if you intended a single version: versions 3 forces HTTP/3-only

Example fix

# before
reverse_proxy localhost:9000 {
	transport http {
		versions 2.0 1
	}
}
# after
reverse_proxy localhost:9000 {
	transport http {
		versions 1.1 2
	}
}
Defensive patterns

Strategy: validation

Validate before calling

var allowedVersions = map[string]bool{"1.1": true, "2": true, "3": true}
for _, v := range h.Versions {
	if !allowedVersions[v] {
		return fmt.Errorf("bad version %q; want 1.1, 2 or 3", v)
	}
}

Prevention

When it happens

Trigger: Setting `transport http { versions 2.0 }`, `versions h2c`, `versions HTTP/2`, or `versions 1 2` (bare "1" is not valid — it is "1.1"). In JSON, the Transport versions array containing any non-allowed value.

Common situations: Assuming nginx-style version tokens (http2, 1.0), typos like `verions`, or copying config between Caddy versions without checking the directive's allowed values.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/5954860cb4e5b00a. Report an issue: GitHub.