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.Conn

View on GitHub (pinned to e6d6a821db)

Solutions

  1. Read the wrapped inner error: fix the root cause (connection refused -> server down/wrong port; timeout -> firewall/routing)
  2. Verify the client's server address/port and key configuration match the running server
  3. Confirm the tunnel server process is up and listening (ss/netstat on the server) and the port is open in firewalls
  4. 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

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


AI-assisted analysis of snail007/goproxy@e6d6a821db (2026-09-03). Data as JSON: /api/errors/689cede441e9b955. Report an issue: GitHub.