shadow1ng/fscan · error
NODE_RDP_PROTOCOL_T125_MCS_SERVER_REJECT_USER
NODE_RDP_PROTOCOL_T125_MCS_SERVER_REJECT_USER
Error message
NODE_RDP_PROTOCOL_T125_MCS_SERVER_REJECT_USER'
What it means
After a valid ATTACH_USER_CONFIRM header, recvAttachUserConfirm reads a PER-encoded result enumerator; 0 means the user attach succeeded, any non-zero result means the server refused to attach the user channel. The library emits this sentinel error (note the trailing quote typo in the message). It is the server explicitly rejecting the MCS Attach User Request.
Source
Thrown at libs/grdp/protocol/t125/mcs.go:385
option, err := core.ReadUInt8(r)
if err != nil {
c.Emit("error", err)
return
}
if !readMCSPDUHeader(option, ATTACH_USER_CONFIRM) {
c.Emit("error", errors.New("NODE_RDP_PROTOCOL_T125_MCS_BAD_HEADER"))
return
}
e, err := per.ReadEnumerates(r)
if err != nil {
c.Emit("error", err)
return
}
if e != 0 {
c.Emit("error", errors.New("NODE_RDP_PROTOCOL_T125_MCS_SERVER_REJECT_USER'"))
return
}
userId, _ := per.ReadInteger16(r)
userId += MCS_USERCHANNEL_BASE
c.userId = userId
c.channels = append(c.channels, MCSChannelInfo{userId, "user"})
c.connectChannels()
}
func (c *MCSClient) connectChannels() {
glog.Debug("mcs connectChannels:", c.channelsConnected, ":", len(c.channels))
if c.channelsConnected == len(c.channels) && c.serverNetworkData != nil {
if c.nbChannelRequested < int(c.serverNetworkData.ChannelCount) {
//static virtual channel
chanId := c.serverNetworkData.ChannelIdArray[c.nbChannelRequested]
c.nbChannelRequested++View on GitHub (pinned to 95cc12e753)
Solutions
- Retry later — rejection is often due to the server's concurrent-session or license limit.
- Check server-side logs (Terminal Services / RDP listener) for the reject reason at this timestamp.
- Verify credentials/authentication succeeded earlier; some servers reject MCS attach after failed higher-layer checks.
- Confirm the target allows this client's requested channel configuration (clientNetworkData.ChannelDefArray) — excessive channel requests can trigger rejection.
Example fix
// before
if e != 0 {
c.Emit("error", errors.New("NODE_RDP_PROTOCOL_T125_MCS_SERVER_REJECT_USER'"))
return
}
// after
if e != 0 {
c.Emit("error", fmt.Errorf("NODE_RDP_PROTOCOL_T125_MCS_SERVER_REJECT_USER: result=%d", e))
return
} Defensive patterns
Strategy: retry
Validate before calling
// No pre-call check possible; the result enum arrives in the confirm PDU.
// Guard the consumer:
if attachResult != 0 {
return fmt.Errorf("server rejected attach user (result=%d)", attachResult)
} Try / catch
mcs.On("error", func(err error) {
if strings.Contains(err.Error(), "SERVER_REJECT_USER") {
// back off and retry later; check server session/license limits
}
}) Prevention
- Stay under the server's concurrent RDP session/license limits.
- Check server-side RDP listener logs when rejections repeat.
- Limit requested static virtual channels to what the server allows.
When it happens
Trigger: per.ReadEnumerates returns e != 0 when parsing the server's ATTACH_USER_CONFIRM — the server's result field indicates rejection of the attach user request.
Common situations: Server hit its MCS user-channel/connection limit (license or concurrency cap); the server is misconfigured or a security component blocks the session; connecting to a gateway/broker that rejects raw MCS attach; resource exhaustion on an overloaded terminal server.
Related errors
- bad BER tags
- invalid expected BER tag
- NODE_RDP_PROTOCOL_T125_MCS_BAD_HEADER
- MCS DISCONNECT_PROVIDER_ULTIMATUM
- Invalid expected MCS opcode receive data
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/0986658d5309d12c.
Report an issue: GitHub.