{"record":{"id":"db96a830962bed0c","repo":"shadow1ng/fscan","slug":"mcs-recvdata-get-data-error-v","errorCode":null,"errorMessage":"mcs recvData get data error %v","messagePattern":"mcs recvData get data error (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/grdp/protocol/t125/mcs.go","lineNumber":480,"sourceCode":"\tper.ReadEnumerates(r)\n\tsize, _ := per.ReadLength(r)\n\t// channel ID doesn't match a requested layer\n\tfound := false\n\tchannelName := \"\"\n\tfor _, channel := range c.channels {\n\t\tif channel.ID == channelId {\n\t\t\tfound = true\n\t\t\tchannelName = channel.Name\n\t\t\tbreak\n\t\t}\n\t}\n\tif !found {\n\t\tglog.Error(\"mcs receive data for an unconnected layer\")\n\t\treturn\n\t}\n\tleft, err := core.ReadBytes(int(size), r)\n\tif err != nil {\n\t\tc.Emit(\"error\", errors.New(fmt.Sprintf(\"mcs recvData get data error %v\", err)))\n\t\treturn\n\t}\n\tglog.Debugf(\"mcs emit channel<%s>:%v\", channelName, left)\n\tc.Emit(\"sec\", channelName, left)\n}\n\nfunc (c *MCSClient) recvChannelJoinConfirm(s []byte) {\n\tglog.Debug(\"mcs recvChannelJoinConfirm\", hex.EncodeToString(s))\n\tr := bytes.NewReader(s)\n\toption, err := core.ReadUInt8(r)\n\tif err != nil {\n\t\tc.Emit(\"error\", err)\n\t\treturn\n\t}\n\n\tif !readMCSPDUHeader(option, CHANNEL_JOIN_CONFIRM) {\n\t\tc.Emit(\"error\", errors.New(\"NODE_RDP_PROTOCOL_T125_MCS_WAIT_CHANNEL_JOIN_CONFIRM\"))\n\t\treturn","sourceCodeStart":462,"sourceCodeEnd":498,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/libs/grdp/protocol/t125/mcs.go#L462-L498","documentation":"During MCS (T.125 Multipoint Communication Service) data reception, the layer header was parsed but reading the remaining data payload bytes from the stream failed. The MCSCONNECT layer emits this on its 'error' channel instead of returning a Go error, and then aborts processing of that packet. It almost always means the underlying transport died or the stream was truncated mid-packet.","triggerScenarios":"recvData passes the 'found' check (channel layer is connected), then core.ReadBytes(int(size), r) fails because the TCP connection is closed, reset, or returned fewer bytes than the MCS DomainPDU header advertised.","commonSituations":"Server dropped the RDP connection mid-session; network interruption/NAT timeout while a virtual channel packet is in flight; peer sent a corrupted length field causing the reader to block and then hit a read deadline.","solutions":["Check the wrapped error (%v) for net.Error / io.EOF to confirm the transport died, then reconnect and redo the whole X224/MCS/SEC handshake.","Enable glog debug output to see the channel name and confirm where in the session the stream broke.","Verify there are no intermediate proxies/firewalls with idle timeouts shorter than the RDP session keepalive interval.","If it reproduces deterministically at handshake time, capture traffic and check whether the server's MCS SD length exceeds what the client negotiated (block size mismatch)."],"exampleFix":"// before\nc.Emit(\"error\", errors.New(fmt.Sprintf(\"mcs recvData get data error %v\", err)))\nreturn\n// after\n// treat it as a disconnect signal and reconnect upstream\nif errors.Is(err, io.EOF) || errors.Is(err, net.ErrClosed) {\n    c.Emit(\"disconnect\", err)\n    return\n}\nc.Emit(\"error\", fmt.Errorf(\"mcs recvData get data error %w\", err))","handlingStrategy":"try-catch","validationCode":"if conn == nil || conn.RemoteAddr() == nil {\n    return errors.New(\"transport not connected before MCS handshake\")\n}","typeGuard":null,"tryCatchPattern":"// listen on the 'error' channel and distinguish transport death\nc.On(\"error\", func(err error) {\n    if strings.Contains(err.Error(), \"mcs recvData get data error\") {\n        reconnect() // transport-level failure\n    }\n})","preventionTips":["Enable RDP-level keepalives to detect dead connections before a mid-packet read fails","Monitor connection health and reconnect on any MCS 'error' emit","Avoid proxies with aggressive idle timeouts"],"tags":["rdp","mcs","network","stream-truncated"],"backgroundTag":"network-request-failed","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"}