ginuerzh/gost · error

[socks4] %d

Error message

[socks4] %d

What it means

The SOCKS4 server's reply code was not gosocks4.Granted, so the connect request was refused. The library wraps the numeric reply code into this error, letting the caller distinguish refusal reasons (e.g. rejected, ident failure) per the SOCKS4 spec.

Source

Thrown at socks.go:741

	if err := req.Write(conn); err != nil {
		return nil, err
	}

	if Debug {
		log.Logf("[socks4] %s", req)
	}

	reply, err := gosocks4.ReadReply(conn)
	if err != nil {
		return nil, err
	}

	if Debug {
		log.Logf("[socks4] %s", reply)
	}

	if reply.Code != gosocks4.Granted {
		return nil, fmt.Errorf("[socks4] %d", reply.Code)
	}

	return conn, nil
}

type socks4aConnector struct{}

// SOCKS4AConnector creates a Connector for SOCKS4A proxy client.
func SOCKS4AConnector() Connector {
	return &socks4aConnector{}
}

func (c *socks4aConnector) Connect(conn net.Conn, address string, options ...ConnectOption) (net.Conn, error) {
	return c.ConnectContext(context.Background(), conn, "tcp", address, options...)
}

func (c *socks4aConnector) ConnectContext(ctx context.Context, conn net.Conn, network, address string, options ...ConnectOption) (net.Conn, error) {
	switch network {

View on GitHub (pinned to a33fdbf4c9)

Solutions

  1. Decode the reply code (90 granted, 91 rejected/failed, 92 ident-no-connection, 93 ident-mismatch) and check the corresponding condition on the proxy.
  2. Add the destination to the proxy's allow list or fix identd setup (92/93 codes).
  3. Upgrade to the socks4a connector if the target is specified by hostname (DNS must be done by the proxy).
  4. Verify the target is reachable from the proxy host itself.

Example fix

// before
// SOCKS4 to hostname-based target -> reply 91
c := SOCKS4Connector("socks4://proxy:1080")
// after
c := SOCKS4aConnector("socks4a://proxy:1080") // hostname resolved by proxy
Defensive patterns

Strategy: try-catch

Validate before calling

host, port, err := net.SplitHostPort(address)
if err != nil || host == "" || port == "" {
	return fmt.Errorf("socks4 requires an IP literal and port, got %q", address)
}
if net.ParseIP(host) == nil {
	return fmt.Errorf("%s is not an IP; use socks4a", host)
}

Try / catch

conn, err := socks4Connector.ConnectContext(ctx, conn, "tcp", addr)
if err != nil {
	var code int
	if n, _ := fmt.Sscanf(err.Error(), "[socks4] %d", &code); n == 1 {
		switch code {
		case 91: // request rejected/failed
		case 92, 93: // ident problems
		}
		return fmt.Errorf("proxy refused (code %d)", code)
	}
	return err
}

Prevention

When it happens

Trigger: socks4Connector.ConnectContext (tcp-family) sends the SOCKS4 CONNECT request; the reply code != 0x5A (Granted): target refused/unreachable from proxy, proxy rule denies the destination, or identd check failed.

Common situations: SOCKS4 proxy ACLs blocking the target host:port; target server down or refusing connections from the proxy's IP; SOCKS4 deployments requiring ident that fail ident verification; using SOCKS4 for destinations that need SOCKS4a hostname support.

Related errors


AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02). Data as JSON: /api/errors/76eb15a1e878019b. Report an issue: GitHub.