shadow1ng/fscan · warning
netbios_smb_negotiate_send_failed: %w
Error message
netbios_smb_negotiate_send_failed: %w
What it means
This error occurs in queryNetBIOSSession when writing the SMB negotiate packet (smbNegotiate1) to a NetBIOS session service TCP connection on port 139 fails. The library wraps the underlying net.Conn.Write error with the i18n message 'netbios_smb_negotiate_send_failed'. It means the TCP connection was established (DialTCP succeeded) but broke before the first SMB packet could be delivered.
Source
Thrown at plugins/services/netbios.go:217
_ = conn.SetDeadline(time.Now().Add(session.Config.ModuleTimeout()))
// 发送SMB协商数据包
smbNegotiate1 := []byte{
0x00, 0x00, 0x00, 0x85, 0xFF, 0x53, 0x4D, 0x42, 0x72, 0x00, 0x00, 0x00, 0x00, 0x18, 0x53, 0xC8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x02, 0x50, 0x43, 0x20, 0x4E, 0x45, 0x54, 0x57, 0x4F,
0x52, 0x4B, 0x20, 0x50, 0x52, 0x4F, 0x47, 0x52, 0x41, 0x4D, 0x20, 0x31, 0x2E, 0x30, 0x00, 0x02,
0x4C, 0x41, 0x4E, 0x4D, 0x41, 0x4E, 0x31, 0x2E, 0x30, 0x00, 0x02, 0x57, 0x69, 0x6E, 0x64, 0x6F,
0x77, 0x73, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x57, 0x6F, 0x72, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x70,
0x73, 0x20, 0x33, 0x2E, 0x31, 0x61, 0x00, 0x02, 0x4C, 0x4D, 0x31, 0x2E, 0x32, 0x58, 0x30, 0x30,
0x32, 0x00, 0x02, 0x4C, 0x41, 0x4E, 0x4D, 0x41, 0x4E, 0x32, 0x2E, 0x31, 0x00, 0x02, 0x4E, 0x54,
0x20, 0x4C, 0x4D, 0x20, 0x30, 0x2E, 0x31, 0x32, 0x00,
}
_, err = conn.Write(smbNegotiate1)
if err != nil {
return nil, fmt.Errorf("%s: %w", i18n.GetText("netbios_smb_negotiate_send_failed"), err)
}
response1 := make([]byte, 1024)
_, err = conn.Read(response1)
if err != nil {
return nil, fmt.Errorf("%s: %w", i18n.GetText("netbios_smb_negotiate_read_failed"), err)
}
// 发送Session Setup请求
smbSessionSetup := []byte{
0x00, 0x00, 0x01, 0x0A, 0xFF, 0x53, 0x4D, 0x42, 0x73, 0x00, 0x00, 0x00, 0x00, 0x18, 0x07, 0xC8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE,
0x00, 0x00, 0x40, 0x00, 0x0C, 0xFF, 0x00, 0x0A, 0x01, 0x04, 0x41, 0x32, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x00, 0x00, 0xA0, 0xCF, 0x00, 0x60,
0x48, 0x06, 0x06, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x02, 0xA0, 0x3E, 0x30, 0x3C, 0xA0, 0x0E, 0x30,
0x0C, 0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x02, 0x0A, 0xA2, 0x2A, 0x04,
0x28, 0x4E, 0x54, 0x4C, 0x4D, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x82, 0x08,
0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,View on GitHub (pinned to 95cc12e753)
Solutions
- Verify the target host actually speaks SMB on TCP 139 (nmap -p139 --script smb-os-discovery); if it doesn't, exclude it from scanning.
- Increase config.ModuleTimeout() so the SetDeadline does not expire during the write.
- Check for firewalls/IPS between scanner and host that reset SMB packets; whitelist the scanner IP.
- Inspect the wrapped %w error to distinguish i/o timeout vs connection reset and handle each case specifically.
Example fix
// before
conn, err := session.DialTCP(ctx, "tcp", target, session.Config.ModuleTimeout())
_, err = conn.Write(smbNegotiate1)
// after
conn, err := session.DialTCP(ctx, "tcp", target, 2*session.Config.ModuleTimeout())
if err != nil { return nil, err }
if n, werr := conn.Write(smbNegotiate1); werr != nil {
var nerr net.Error
if errors.As(werr, &nerr) && nerr.Timeout() {
return nil, fmt.Errorf("smb negotiate timed out after %v: %w", session.Config.ModuleTimeout(), werr)
}
return nil, fmt.Errorf("%s: %w", i18n.GetText("netbios_smb_negotiate_send_failed"), werr)
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: check TCP 139 reachability and a sane timeout before scanning
if config.ModuleTimeout() < 2*time.Second {
return fmt.Errorf("module timeout %v too short for SMB negotiate", config.ModuleTimeout())
}
conn, err := net.DialTimeout("tcp", host+":139", config.ModuleTimeout())
if err != nil {
return fmt.Errorf("host %s not reachable on TCP 139: %w", host, err)
}
_ = conn.Close() Type guard
func isNetError(err error) (net.Error, bool) {
var nerr net.Error
if errors.As(err, &nerr) {
return nerr, true
}
return nil, false
} Try / catch
info, err := plugin.Scan(ctx, host, session)
if err != nil {
var nerr net.Error
if errors.As(err, &nerr) && nerr.Timeout() {
log.Printf("skip %s: negotiate send timeout", host)
return nil // treat as no NetBIOS service
}
if errors.Is(err, syscall.ECONNRESET) || errors.Is(err, syscall.EPIPE) {
log.Printf("skip %s: connection reset during negotiate", host)
return nil
}
return err
} Prevention
- Set ModuleTimeout generously (>=5s) for cross-WAN scans.
- Pre-check TCP 139 reachability before running the full session flow.
- Exclude known non-SMB hosts (printers, IoT) from NetBIOS scanning.
- Always inspect the wrapped error with errors.Is/errors.As instead of treating all failures alike.
When it happens
Trigger: Calling Scan -> queryNetBIOSSession against a host where TCP 139 accepts the connection but the write fails: connection reset by peer immediately after accept, connection closed by the remote host mid-write, or the deadline set via SetDeadline(ModuleTimeout) expiring during the write.
Common situations: Windows hosts with SMB disabled but NetBIOS port-filtering middleware that accepts and drops connections; firewalls/IPS that RST SMB traffic; host crashed or rebooted between dial and write; extremely short ModuleTimeout values causing i/o timeout; scanning hosts that only expose UDP 137 but have a half-open TCP 139 listener.
Related errors
- netbios_smb_negotiate_read_failed: %w
- netbios_smb_session_send_failed: %w
- ms17010_connection_error: %w
- ms17010_send_session_error: %w
- ms17010_send_tree_error: %w
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/9bccda7d8bc1dd2d.
Report an issue: GitHub.