fatedier/frp · critical

create vhost http listener error, %v

Error message

create vhost http listener error, %v

What it means

When vhostHTTPPort > 0 and HTTP is not multiplexed onto the main listener (httpMuxOn false), frps binds a dedicated TCP listener on ProxyBindAddr:VhostHTTPPort for HTTP vhost routing. A bind failure here is fatal to service creation.

Source

Thrown at server/service.go:319

		svr.rc.HTTPReverseProxy = rp

		address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPPort))
		protocols := new(http.Protocols)
		protocols.SetHTTP1(true)
		protocols.SetUnencryptedHTTP2(true)
		server := &http.Server{
			Addr:              address,
			Handler:           rp,
			ReadHeaderTimeout: 60 * time.Second,
			Protocols:         protocols,
		}
		var l net.Listener
		if httpMuxOn {
			l = svr.muxer.ListenHTTP(1)
		} else {
			l, err = net.Listen("tcp", address)
			if err != nil {
				return nil, fmt.Errorf("create vhost http listener error, %v", err)
			}
		}
		go func() {
			_ = server.Serve(l)
		}()
		log.Infof("http service listen on %s", address)
	}

	// Create https vhost muxer.
	if cfg.VhostHTTPSPort > 0 {
		var l net.Listener
		if httpsMuxOn {
			l = svr.muxer.ListenHTTPS(1)
		} else {
			address := net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPSPort))
			l, err = net.Listen("tcp", address)
			if err != nil {
				return nil, fmt.Errorf("create server listener error, %v", err)

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Stop the conflicting service or move vhostHTTPPort to a free port
  2. Update every http-type proxy/custom domain DNS or reverse proxy that targets the old port
  3. Alternatively set bindPort = vhostHTTPPort to multiplex HTTP onto the main listener (httpMuxOn) and avoid the extra bind

Example fix

# before
bindPort = 7000
vhostHTTPPort = 8080   # nginx already on 8080

# after
bindPort = 7000
vhostHTTPPort = 8090
Defensive patterns

Strategy: validation

Validate before calling

if cfg.VhostHTTPPort > 0 && cfg.BindPort != cfg.VhostHTTPPort {
    if l, err := net.Listen("tcp", net.JoinHostPort(cfg.ProxyBindAddr, strconv.Itoa(cfg.VhostHTTPPort))); err != nil {
        return fmt.Errorf("vhost http port %d unavailable: %w", cfg.VhostHTTPPort, err)
    } else { l.Close() }
}

Prevention

When it happens

Trigger: vhostHTTPPort colliding with another web server on the host (nginx, apache, another frps); ProxyBindAddr invalid; privileged port without capability.

Common situations: Running frps on a box that already serves HTTP on 80; two frps instances sharing a host; setting vhostHTTPPort = 8080 where 8080 is taken.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/608daee111a08cd0. Report an issue: GitHub.