shadow1ng/fscan · error
ReadConnectResponse %v
Error message
ReadConnectResponse %v
What it means
recvConnectResponse is the 'data' handler waiting for the server's MCS Connect Response. It calls ReadConnectResponse on the raw bytes; any parse failure (bad application tag, bad enumerated result, bad BER tags, invalid octet string tag) is re-wrapped as 'ReadConnectResponse %v' and emitted as an error. It means the server's MCS Connect Response could not be decoded.
Source
Thrown at libs/grdp/protocol/t125/mcs.go:314
dataBuff := &bytes.Buffer{}
ber.WriteApplicationTag(uint8(MCS_TYPE_CONNECT_INITIAL), len(connectInitialBerEncoded), dataBuff)
dataBuff.Write(connectInitialBerEncoded)
_, err := c.transport.Write(dataBuff.Bytes())
if err != nil {
c.Emit("error", errors.New(fmt.Sprintf("mcs sendConnectInitial write error %v", err)))
return
}
glog.Debug("mcs wait for data event")
c.transport.Once("data", c.recvConnectResponse)
}
func (c *MCSClient) recvConnectResponse(s []byte) {
glog.Debug("mcs recvConnectResponse", hex.EncodeToString(s))
cResp, err := ReadConnectResponse(bytes.NewReader(s))
if err != nil {
c.Emit("error", errors.New(fmt.Sprintf("ReadConnectResponse %v", err)))
return
}
// record server gcc block
serverSettings := gcc.ReadConferenceCreateResponse(cResp.userData)
for _, v := range serverSettings {
switch v.(type) {
case *gcc.ServerSecurityData:
c.serverSecurityData = v.(*gcc.ServerSecurityData)
case *gcc.ServerCoreData:
c.serverCoreData = v.(*gcc.ServerCoreData)
case *gcc.ServerNetworkData:
c.serverNetworkData = v.(*gcc.ServerNetworkData)
default:
err := errors.New(fmt.Sprintf("unhandle server gcc block %v", reflect.TypeOf(v)))
glog.Error(err)View on GitHub (pinned to 95cc12e753)
Solutions
- Check the hex dump logged at the top of recvConnectResponse: the first byte should indicate an MCS Connect Response (0x66<<2 pattern with BER application tag).
- Verify the peer is a genuine RDP server on the expected port.
- Check whether the server requires NLA and terminates the handshake early; handle security protocol negotiation before MCS.
- Add the wrapped cause (%v) inspection — the inner error names exactly which BER step failed.
Example fix
// before
cResp, err := ReadConnectResponse(bytes.NewReader(s))
if err != nil {
c.Emit("error", errors.New(fmt.Sprintf("ReadConnectResponse %v", err)))
return
}
// after
cResp, err := ReadConnectResponse(bytes.NewReader(s))
if err != nil {
c.Emit("error", fmt.Errorf("ReadConnectResponse: %w", err))
c.transport.Close()
return
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the response prefix is an MCS Connect Response before full parse:
func isConnectResponse(b []byte) bool {
return len(b) > 2 && (b[0]&0xfc)>>2 == 0x66>>0 // BER app tag 0x66 pattern
} Try / catch
mcs.On("error", func(err error) {
if strings.Contains(err.Error(), "ReadConnectResponse") {
// log hex dump, verify server identity/protocol, retry
}
}) Prevention
- Probe the port with an RDP-capable client before running this library against unknown hosts.
- Always inspect the logged hex dump when the response fails to parse.
- Support the server's negotiated security protocol before the MCS handshake.
When it happens
Trigger: The once-registered transport 'data' handler recvConnectResponse receives bytes for which ReadConnectResponse returns an error — wrong application tag (not MCS_TYPE_CONNECT_RESPONSE 0x66), failed BER parsing, or truncated userData.
Common situations: Connecting to a non-RDP service that replies with garbage; the server rejects the connection with a Connect Response carrying a non-zero result encoded unexpectedly; TCP coalescing/fragmentation delivers partial frames; server sent a security-negotiation failure instead of the MCS response.
Related errors
- mcs sendConnectInitial write error %v
- unsupported Capability type 0x%04x
- Unknown data pdu type2 0x%02x
- Unsupport slow update type 0x%x
- invalid length in Auto-Reconnect packet
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/1d1f66959836721a.
Report an issue: GitHub.