fatedier/frp · error

connect to server error: %v

Error message

connect to server error: %v

What it means

Thrown by BaseVisitor.dialRawVisitorConn when the visitor's helper.ConnectServer() — the control-connected TCP/TLS dial to frps — fails before it can send the NewVisitorConn message. The visitor cannot reach the frps server at all; the %v carries the dial error (timeout, refused, TLS, DNS).

Source

Thrown at client/visitor/visitor.go:168

	}
}

func (v *BaseVisitor) Close() {
	if v.l != nil {
		v.l.Close()
	}
	if v.internalLn != nil {
		v.internalLn.Close()
	}
	if v.plugin != nil {
		v.plugin.Close()
	}
}

func (v *BaseVisitor) dialRawVisitorConn(cfg *v1.VisitorBaseConfig) (net.Conn, error) {
	visitorConn, err := v.helper.ConnectServer()
	if err != nil {
		return nil, fmt.Errorf("connect to server error: %v", err)
	}

	now := time.Now().Unix()
	targetProxyName := naming.BuildTargetServerProxyName(v.clientCfg.User, cfg.ServerUser, cfg.ServerName)
	newVisitorConnMsg := &msg.NewVisitorConn{
		RunID:          v.helper.RunID(),
		ProxyName:      targetProxyName,
		SignKey:        util.GetAuthKey(cfg.SecretKey, now),
		Timestamp:      now,
		UseEncryption:  cfg.Transport.UseEncryption,
		UseCompression: cfg.Transport.UseCompression,
	}
	err = visitorConn.WriteMsg(newVisitorConnMsg)
	if err != nil {
		visitorConn.Close()
		return nil, fmt.Errorf("send newVisitorConnMsg to server error: %v", err)
	}

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Read the wrapped %v: 'connection refused' → wrong port or frps down; 'i/o timeout' → firewall/NAT; TLS errors → transport.tls mismatch.
  2. Verify frps is running and reachable: nc -vz serverAddr serverPort from the visitor host.
  3. Align transport.tls.enable and related TLS settings between frpc and frps.
  4. If frps restarts frequently, ensure frpc's control connection re-login works (auth still valid) so visitors can redial.

Example fix

# before
serverAddr = "192.168.1.50"
serverPort = 8000   # wrong port

# after
serverAddr = "192.168.1.50"
serverPort = 7000
Defensive patterns

Strategy: retry

Validate before calling

// Verify frps reachability before starting visitors
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", serverAddr, serverPort), 3*time.Second)
if err != nil { return fmt.Errorf("frps unreachable, visitor will fail: %w", err) }
conn.Close()

Try / catch

// Visitors retry in their loops; in custom wrapping code classify the error
if err := visitor.Run(); err != nil {
    if strings.Contains(err.Error(), "connect to server error") {
        log.Warnf("frps dial failed, retrying after backoff: %v", err)
        time.Sleep(backoff) // then retry visitor creation
    }
}

Prevention

When it happens

Trigger: An stcp/sudp/xtcp visitor attempting a new visitor connection when the frps address is wrong/unreachable, the TLS settings mismatch, or the shared control connection's server has gone away; ConnectServer returns the transport-level error which is wrapped here.

Common situations: serverAddr/serverPort typo in the visitor's client config; frps restarted and visitor reconnect racing; transport.tls.enable differing between frpc and frps; NAT/firewall blocking the visitor's outbound connection to frps.

Related errors


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