caddyserver/caddy · error
server listening on %v is configured for HTTPS and cannot na
Error message
server listening on %v is configured for HTTPS and cannot natively multiplex HTTP and HTTPS: %s
What it means
The same Caddy server (same listener set) received both HTTP and HTTPS site addresses. Go's net/http cannot multiplex cleartext and TLS on one listener, so the adapter refuses to build a server that mixes `http://` and `https://` addresses on the same socket.
Source
Thrown at caddyconfig/httpcaddyfile/httptype.go:1151
return nil, false
}
return sni, true
}
func detectConflictingSchemes(srv *caddyhttp.Server, serverBlocks []serverBlock, options map[string]any) error {
httpPort := strconv.Itoa(caddyhttp.DefaultHTTPPort)
if hp, ok := options["http_port"].(int); ok {
httpPort = strconv.Itoa(hp)
}
httpsPort := strconv.Itoa(caddyhttp.DefaultHTTPSPort)
if hsp, ok := options["https_port"].(int); ok {
httpsPort = strconv.Itoa(hsp)
}
var httpOrHTTPS string
checkAndSetHTTP := func(addr Address) error {
if httpOrHTTPS == "HTTPS" {
errMsg := fmt.Errorf("server listening on %v is configured for HTTPS and cannot natively multiplex HTTP and HTTPS: %s",
srv.Listen, addr.Original)
if addr.Scheme == "" && addr.Host == "" {
errMsg = fmt.Errorf("%s (try specifying https:// in the address)", errMsg)
}
return errMsg
}
if len(srv.TLSConnPolicies) > 0 {
// any connection policies created for an HTTP server
// is a logical conflict, as it would enable HTTPS
return fmt.Errorf("server listening on %v is HTTP, but attempts to configure TLS connection policies", srv.Listen)
}
httpOrHTTPS = "HTTP"
return nil
}
checkAndSetHTTPS := func(addr Address) error {
if httpOrHTTPS == "HTTP" {
return fmt.Errorf("server listening on %v is configured for HTTP and cannot natively multiplex HTTP and HTTPS: %s",
srv.Listen, addr.Original)View on GitHub (pinned to 50e54ee279)
Solutions
- Give the HTTP site its own port (default :80) and let HTTPS stay on :443
- Remove the `http://` scheme from the address if HTTPS was intended on that port
- Use distinct `bind` addresses so they do not land in the same server
- Enable `auto_https disable_redirects` if you were only trying to suppress the HTTP redirect
Example fix
# before
http://example.com:443 {
respond "plain"
}
https://example.com:443 {
respond "tls"
}
# after
http://example.com:80 {
respond "plain"
}
https://example.com {
respond "tls"
} Defensive patterns
Strategy: validation
Validate before calling
# Before adapting, ensure no listener mixes schemes:
# group addresses by host:port; fail if both http and https appear
for group in group_addresses_by_listener(keys):
schemes = {a.scheme or infer(a.port) for a in group}
assert not ({'http','https'} <= schemes), f"mixed protocols on {group}" Prevention
- Never put http:// sites on the HTTPS port or vice versa
- Let Caddy pick default ports (omit :80/:443) so schemes stay separated
- Use caddy adapt in CI to fail config mixes early
When it happens
Trigger: Two site blocks (or one block) whose keys resolve to the same listen port where one key is `http://example.com` (or matches the configured `http_port`) and another is `https://example.com` or has scheme https on the same port — e.g. `http://example.com` and `https://example.com` both defaulting to ports that share a listener, or explicit `http://example.com:443` next to `https://example.com:443`.
Common situations: Trying to serve both a redirect target and TLS site on one port, mixing `http://` and bare hostnames that default to HTTPS on the same explicit port, or copying a redirect block that reuses the HTTPS port with an http:// scheme.
Related errors
- server listening on %v is configured for HTTP and cannot nat
- %s (try specifying https:// in the address)
- server listening on %v is HTTP, but attempts to configure TL
- request path is missing object ID
- malformed object path
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/32579db1f0618d36.
Report an issue: GitHub.