snail007/goproxy · error
connection err: %s
Error message
connection err: %s
What it means
GetInConn obtains an outbound tunnel connection by calling s.GetConn() and wraps any failure as "connection err: %s". It means the tunnel client could not establish a connection to the tunnel server (or its parent) before writing the handshake packet.
Source
Thrown at services/tunnel_client.go:83
log.Printf("read connection signal err: %s", err)
break
}
log.Printf("signal revecived:%s", signal)
if *s.cfg.IsUDP {
go s.ServeUDP()
} else {
go s.ServeConn()
}
}
}
}
func (s *TunnelClient) Clean() {
s.StopService()
}
func (s *TunnelClient) GetInConn(typ uint8) (outConn net.Conn, err error) {
outConn, err = s.GetConn()
if err != nil {
err = fmt.Errorf("connection err: %s", err)
return
}
keyBytes := []byte(*s.cfg.Key)
keyLength := uint16(len(keyBytes))
pkg := new(bytes.Buffer)
binary.Write(pkg, binary.LittleEndian, typ)
binary.Write(pkg, binary.LittleEndian, keyLength)
binary.Write(pkg, binary.LittleEndian, keyBytes)
_, err = outConn.Write(pkg.Bytes())
if err != nil {
err = fmt.Errorf("write connection data err: %s ,retrying...", err)
utils.CloseConn(&outConn)
return
}
return
}
func (s *TunnelClient) GetConn() (conn net.Conn, err error) {
var _conn tls.ConnView on GitHub (pinned to e6d6a821db)
Solutions
- Read the wrapped inner error: fix the root cause (connection refused -> server down/wrong port; timeout -> firewall/routing)
- Verify the client's server address/port and key configuration match the running server
- Confirm the tunnel server process is up and listening (ss/netstat on the server) and the port is open in firewalls
- If pool exhaustion is the cause, increase connection limits or reduce client concurrency
Example fix
// before (wrong port in client config -> GetConn fails) // server_addr=1.2.3.4:9999 // after // server_addr=1.2.3.4:8024
Defensive patterns
Strategy: retry
Validate before calling
addr := net.JoinHostPort(cfg.ServerIP, cfg.ServerPort)
if conn, err := net.DialTimeout("tcp", addr, 5*time.Second); err != nil {
return fmt.Errorf("tunnel server %s unreachable before start: %v", addr, err)
} else { conn.Close() } Try / catch
conn, err := client.GetInConn(typ)
if err != nil {
if strings.Contains(err.Error(), "connection err:") {
// inspect wrapped cause; retry with backoff
time.Sleep(time.Second)
conn, err = client.GetInConn(typ)
}
} Prevention
- Pre-flight check server reachability (dial the port) in your startup script
- Keep a health check/reconnect loop in long-running clients
- Align server_ip/server_port and TLS settings between client and server configs
- Open the tunnel port in firewalls/security groups before rollout
When it happens
Trigger: GetConn fails because the tunnel server is unreachable, refusing connections, TLS handshake fails, or the connection pool is exhausted; GetInConn wraps that underlying error and returns it to callers Start, ServeUDP, or ServeConn.
Common situations: Server down or wrong server_ip/server_port in client config; firewall/security group blocking the port; TLS cert mismatch on the tunnel port; server at max connections so the pool cannot hand out a conn.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- write connection data err: %s ,retrying...
- client control conn not exists
- no address Found, net.InterfaceAddrs: %v
- http decoder read err:%s
AI-assisted analysis of snail007/goproxy@e6d6a821db (2026-09-03).
Data as JSON: /api/errors/689cede441e9b955.
Report an issue: GitHub.