shadow1ng/fscan · error
failed to tree connect AndX: %s
Error message
failed to tree connect AndX: %s
What it means
This error wraps a failure of treeConnectAndX in smb1AnonymousConnectIPC (plugins/services/ms17010_exp.go:160). treeConnectAndX sends an SMB1 Tree Connect AndX request for \\host\IPC$ using the logged-in UserID and reads the reply via smb1GetResponse; it can also fail earlier if net.SplitHostPort cannot split the address. The library throws it because the exploit needs an established IPC$ tree (TreeID) before staging the Trans2 packets.
Source
Thrown at plugins/services/ms17010_exp.go:160
_ = conn.Close()
}
}()
err = smbClientNegotiate(conn)
if err != nil {
return nil, nil, fmt.Errorf("failed to negotiate: %s", err)
}
raw, header, err := smb1AnonymousLogin(conn)
if err != nil {
return nil, nil, fmt.Errorf("failed to login with anonymous: %s", err)
}
_, err = getOSName(raw)
if err != nil {
return nil, nil, fmt.Errorf("failed to get OS name: %s", err)
}
//fmt.Println("OS:", osName)
header, err = treeConnectAndX(conn, address, header.UserID)
if err != nil {
return nil, nil, fmt.Errorf("failed to tree connect AndX: %s", err)
}
ok = true
return header, conn, nil
}
const smbHeaderSize = 32
type smbHeader struct {
ServerComponent [4]byte
SMBCommand uint8
ErrorClass uint8
Reserved byte
ErrorCode uint16
Flags uint8
Flags2 uint16
ProcessIDHigh uint16
Signature [8]byte
Reserved2 [2]byteView on GitHub (pinned to 95cc12e753)
Solutions
- Ensure the address is in host:port form — a missing port makes SplitHostPort fail before anything is sent
- Check the tree-connect response's NT status; ACCESS_DENIED means IPC$ null sessions are blocked on the target
- Inspect the wrapped smb1GetResponse error for reset vs timeout and retry accordingly
- Confirm the anonymous login succeeded (valid UserID) since an invalid UserID can cause the tree connect to be rejected
Example fix
// before
header, err = treeConnectAndX(conn, address, header.UserID)
if err != nil {
return nil, nil, fmt.Errorf("failed to tree connect AndX: %s", err)
}
// after
if _, _, err := net.SplitHostPort(address); err != nil {
return nil, nil, fmt.Errorf("invalid address %q (want host:port): %w", address, err)
}
header, err = treeConnectAndX(conn, address, header.UserID)
if err != nil {
return nil, nil, fmt.Errorf("failed to tree connect AndX: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
func validTargetAddress(address string) error {
host, port, err := net.SplitHostPort(address)
if err != nil {
return fmt.Errorf("address %q must be host:port: %w", address, err)
}
if net.ParseIP(host) == nil {
return fmt.Errorf("host %q is not an IP", host)
}
_, err = strconv.Atoi(port)
return err
} Type guard
func isAddressFormatErr(err error) bool {
var addrErr *net.AddrError
return errors.As(err, &addrErr) && addrErr.Err == "missing port in address"
} Try / catch
header, conn, err := smb1AnonymousConnectIPC(addr)
if err != nil {
if isAddressFormatErr(err) || strings.Contains(err.Error(), "failed to tree connect AndX") && missingPort(addr) {
addr = net.JoinHostPort(addr, "445")
return smb1AnonymousConnectIPC(addr)
}
return err
} Prevention
- Always normalize target addresses to host:port before invoking the exploit chain
- Check IPC$ accessibility (null-session policy) on Windows targets beforehand
- Inspect the tree-connect NT status in the response to distinguish ACCESS_DENIED from transport failure
- Reuse the negotiated UserID from login — expired/invalid UserIDs cause rejections
When it happens
Trigger: net.SplitHostPort fails on a malformed address (no host:port form), the packet write fails, or smb1GetResponse fails on the tree-connect reply (NetBIOS read error/timeout, invalid message type, response shorter than 32 bytes, incomplete body, unparseable header).
Common situations: Address passed without a port (e.g. "10.0.0.5" instead of "10.0.0.5:445"); server denies access to IPC$ even for anonymous sessions; connection dropped mid-session by the target or an IDS; timeouts on slow targets.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- failed to negotiate: %s
- ms17010_connection_error: %w
- ms17010_send_protocol_error: %w
- ms17010_smbv1_unsupported
- ms17010_send_session_error: %w
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/a64473d09870a610.
Report an issue: GitHub.