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.
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
AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15).
Data as JSON: /api/errors/742c6454525fe678.
Report an issue: GitHub.
Appendix: 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)