fatedier/frp · warning
host header rewrite failed
Error message
host header rewrite failed
What it means
In vhost Listener.Accept, after a connection is accepted the muxer optionally rewrites the HTTP Host header (feature used by frp's host-header rewriting for http proxies with rewriteHost). If that rewrite function fails to parse/wrap the connection's first request, the raw error is logged (Warnf) and this generic error is returned instead of the connection. The connection is dropped, not retried.
Source
Thrown at pkg/util/vhost/vhost.go:252
accept chan net.Conn
ctx context.Context
}
func (l *Listener) Accept() (net.Conn, error) {
xl := xlog.FromContextSafe(l.ctx)
conn, ok := <-l.accept
if !ok {
return nil, fmt.Errorf("listener closed")
}
// if rewriteHost func is exist
// rewrite http requests with a modified host header
// if l.rewriteHost is empty, nothing to do
if l.mux.rewriteHost != nil {
sConn, err := l.mux.rewriteHost(conn, l.rewriteHost)
if err != nil {
xl.Warnf("host header rewrite failed: %v", err)
return nil, fmt.Errorf("host header rewrite failed")
}
xl.Debugf("rewrite host to [%s] success", l.rewriteHost)
conn = sConn
}
return netpkg.NewContextConn(l.ctx, conn), nil
}
func (l *Listener) Close() error {
l.mux.registryRouter.Del(l.name, l.location, l.routeByHTTPUser)
close(l.accept)
return nil
}
func (l *Listener) Name() string {
return l.name
}
func (l *Listener) Addr() net.Addr {View on GitHub (pinned to 6c8a8d0a97)
Solutions
- Send valid HTTP/1.x requests on the plain vhost port; use vhostHTTPSPort (type=https) for TLS traffic
- Check the accompanying Warnf line — it contains the underlying cause (e.g. malformed request, connection reset)
- If a proxy needs the original Host preserved, disable host rewriting for that proxy so this code path is skipped
Example fix
# before curl https://frps:8080/ # TLS bytes to plain http vhost port with rewrite # after curl http://frps:8080/ # plain HTTP on vhostHTTPPort
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure only well-formed plain HTTP/1.x hits a rewriting vhost listener // (send TLS only to the https vhost port)
Try / catch
conn, err := vl.Accept()
if err != nil {
if strings.Contains(err.Error(), "host header rewrite failed") {
xl.Warnf("dropped non-HTTP/malformed conn: %v", err)
continue // drop just this conn; the listener stays usable
}
return err
} Prevention
- Point HTTPS clients at vhostHTTPSPort, never vhostHTTPPort
- Exclude TCP health probes from vhost ports or teach them HTTP
- Watch frps Warnf logs for the underlying rewrite cause when triaging
When it happens
Trigger: A client connects to a vhost listener configured with host rewriting and sends data that is not a parseable HTTP request (binary, TLS bytes to a plain port, truncated request); the rewrite wrapper encounters an I/O error reading the first bytes; extremely long/malformed request headers.
Common situations: HTTPS traffic sent to vhostHTTPPort (plaintext) where rewriting is enabled; health-check TCP probes that connect and send non-HTTP bytes; clients disconnecting mid-request so the header read fails.
Related errors
- no route found
- %v: %s %s %s
- listener closed
- create vhost http listener error, %v
- HTTP ${response.status}
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/742c6454525fe678.
Report an issue: GitHub.