shadow1ng/fscan · warning
i18n.GetText("empty_response_received")
Error message
i18n.GetText("empty_response_received") What it means
After sending the probe packet, checkMongoAuth reads the reply; if the connection yields zero bytes (clean close with no data), it reports the localized 'empty_response_received' error. A real MongoDB must answer an OP_MSG with at least a protocol header, so an empty read means the peer is not speaking MongoDB or dropped the connection.
Source
Thrown at plugins/services/mongodb.go:675
if _, writeErr := conn.Write(packet); writeErr != nil {
return "", writeErr
}
select {
case <-ctx.Done():
return "", ctx.Err()
default:
}
reply := make([]byte, 2048)
count, err := conn.Read(reply)
if err != nil && err != io.EOF {
return "", err
}
if count == 0 {
return "", fmt.Errorf("%s", i18n.GetText("empty_response_received"))
}
return string(reply[:count]), nil
}
func createOpMsgPacket() []byte {
return []byte{
0x69, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xdd, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00,
0x00, 0x02, 0x67, 0x65, 0x74, 0x4c, 0x6f, 0x67,
0x00, 0x10, 0x00, 0x00, 0x00, 0x73, 0x74, 0x61,
0x72, 0x74, 0x75, 0x70, 0x57, 0x61, 0x72, 0x6e,
0x69, 0x6e, 0x67, 0x73, 0x00, 0x02, 0x24, 0x64,
0x62, 0x00, 0x06, 0x00, 0x00, 0x00, 0x61, 0x64,
0x6d, 0x69, 0x6e, 0x00, 0x03, 0x6c, 0x73, 0x69,
0x64, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x05, 0x69,
0x64, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x6e,View on GitHub (pinned to 95cc12e753)
Solutions
- Identify what actually listens on the port (banner grab, nmap -sV) before MongoDB-specific checks
- Check mongod logs for connection rejections or max-connection limits
- Disable tcpwrappers/connThrottle or allowlist the scanner IP
- Send a valid hello handshake and confirm a structured BSON reply comes back
Defensive patterns
Strategy: retry
Validate before calling
conn.SetReadDeadline(time.Now().Add(timeout))
n, err := conn.Read(buf)
if err == io.EOF && n == 0 {
return errors.New("peer closed without responding — likely not MongoDB")
} Type guard
func isEmptyResponse(n int, err error) bool {
return n == 0 && (err == io.EOF || err == nil)
} Try / catch
reply, err := checkMongoAuth(ctx, addr, packet, session)
if err != nil {
if strings.Contains(i18nText(err), "empty_response") {
if r2, e2 := checkMongoAuth(ctx, addr, packet, session); e2 == nil {
reply = r2
} else {
log.Warn("target closes connections without replying")
}
return
}
return err
} Prevention
- Identify the listening service before sending binary MongoDB probes
- Retry once on immediate EOF (throttling can cause one-off closes)
- Watch server logs for connection limits (maxIncomingConnections)
When it happens
Trigger: conn.Read returns count==0 (typically with io.EOF) right after the write — the remote closed without responding, e.g. because it is not a MongoDB server or it rejects the crafted packet.
Common situations: Port occupied by an HTTP or other plain-text service that closes on binary input; mongod with aggressive connection throttling closing immediately; tcpwrapped services in inetd-style wrappers.
Related errors
- short oracle data packet
- oracle resend is not supported
- %s: %w [socks5_handshake_read_failed]
- %s [socks5_unsupported_version]
- %s
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/e30915325228d3cd.
Report an issue: GitHub.