{"record":{"id":"e30915325228d3cd","repo":"shadow1ng/fscan","slug":"i18n-gettext-empty-response-received","errorCode":null,"errorMessage":"i18n.GetText(\"empty_response_received\")","messagePattern":"i18n\\.GetText\\(\"empty_response_received\"\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"plugins/services/mongodb.go","lineNumber":675,"sourceCode":"\n\tif _, writeErr := conn.Write(packet); writeErr != nil {\n\t\treturn \"\", writeErr\n\t}\n\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn \"\", ctx.Err()\n\tdefault:\n\t}\n\n\treply := make([]byte, 2048)\n\tcount, err := conn.Read(reply)\n\tif err != nil && err != io.EOF {\n\t\treturn \"\", err\n\t}\n\n\tif count == 0 {\n\t\treturn \"\", fmt.Errorf(\"%s\", i18n.GetText(\"empty_response_received\"))\n\t}\n\n\treturn string(reply[:count]), nil\n}\n\nfunc createOpMsgPacket() []byte {\n\treturn []byte{\n\t\t0x69, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,\n\t\t0x00, 0x00, 0x00, 0x00, 0xdd, 0x07, 0x00, 0x00,\n\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00,\n\t\t0x00, 0x02, 0x67, 0x65, 0x74, 0x4c, 0x6f, 0x67,\n\t\t0x00, 0x10, 0x00, 0x00, 0x00, 0x73, 0x74, 0x61,\n\t\t0x72, 0x74, 0x75, 0x70, 0x57, 0x61, 0x72, 0x6e,\n\t\t0x69, 0x6e, 0x67, 0x73, 0x00, 0x02, 0x24, 0x64,\n\t\t0x62, 0x00, 0x06, 0x00, 0x00, 0x00, 0x61, 0x64,\n\t\t0x6d, 0x69, 0x6e, 0x00, 0x03, 0x6c, 0x73, 0x69,\n\t\t0x64, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x05, 0x69,\n\t\t0x64, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x6e,","sourceCodeStart":657,"sourceCodeEnd":693,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/mongodb.go#L657-L693","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"conn.SetReadDeadline(time.Now().Add(timeout))\nn, err := conn.Read(buf)\nif err == io.EOF && n == 0 {\n    return errors.New(\"peer closed without responding — likely not MongoDB\")\n}","typeGuard":"func isEmptyResponse(n int, err error) bool {\n    return n == 0 && (err == io.EOF || err == nil)\n}","tryCatchPattern":"reply, err := checkMongoAuth(ctx, addr, packet, session)\nif err != nil {\n    if strings.Contains(i18nText(err), \"empty_response\") {\n        if r2, e2 := checkMongoAuth(ctx, addr, packet, session); e2 == nil {\n            reply = r2\n        } else {\n            log.Warn(\"target closes connections without replying\")\n        }\n        return\n    }\n    return err\n}","preventionTips":["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)"],"tags":["mongodb","network","empty-response","protocol"],"backgroundTag":"empty-response-body","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}