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

  1. Retry later — rejection is often due to the server's concurrent-session or license limit.
  2. Check server-side logs (Terminal Services / RDP listener) for the reject reason at this timestamp.
  3. Verify credentials/authentication succeeded earlier; some servers reject MCS attach after failed higher-layer checks.
  4. 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

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


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/0986658d5309d12c. Report an issue: GitHub.