shadow1ng/fscan · error

mcs sendConnectInitial write error %v

Error message

mcs sendConnectInitial write error %v

What it means

In MCSClient.connect, after building and BER-encoding the MCS Connect Initial PDU (carrying GCC client data), it is written to the transport. If transport.Write fails, the error is wrapped as 'mcs sendConnectInitial write error %v' and emitted on the 'error' channel. It is a low-level socket write failure during the MCS handshake.

Source

Thrown at libs/grdp/protocol/t125/mcs.go:303

	glog.Debugf("clientNetworkData:%+v", c.clientNetworkData)
	glog.Debugf("clientSecurityData:%+v", c.clientSecurityData)
	// sendConnectclientCoreDataInitial
	userDataBuff := bytes.Buffer{}
	userDataBuff.Write(c.clientCoreData.Pack())
	userDataBuff.Write(c.clientNetworkData.Pack())
	userDataBuff.Write(c.clientSecurityData.Pack())

	ccReq := gcc.MakeConferenceCreateRequest(userDataBuff.Bytes())
	connectInitial := NewConnectInitial(ccReq)
	connectInitialBerEncoded := connectInitial.BER()

	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:

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Inspect the wrapped inner error (%v) to identify the underlying cause (ECONNRESET, broken pipe, timeout).
  2. Verify the server does not require NLA/CredSSP; if it does, the connection is typically torn down at this stage.
  3. Retry the connection; transient network drops are common on WAN links.
  4. Check TLS layer succeeded — a failed TLS handshake often leaves the transport unusable before this write.

Example fix

// before
_, err := c.transport.Write(dataBuff.Bytes())
if err != nil {
    c.Emit("error", errors.New(fmt.Sprintf("mcs sendConnectInitial write error %v", err)))
    return
}
// after
_, err := c.transport.Write(dataBuff.Bytes())
if err != nil {
    c.Emit("error", fmt.Errorf("mcs sendConnectInitial write error: %w", err))
    c.transport.Close()
    return
}
Defensive patterns

Strategy: retry

Validate before calling

// Check the transport is still alive before writing:
if c.transport == nil {
    return errors.New("transport not connected")
}

Try / catch

mcs.On("error", func(err error) {
    if strings.Contains(err.Error(), "sendConnectInitial write error") {
        // retry with backoff; surface the wrapped net error to the user
    }
})

Prevention

When it happens

Trigger: The call c.transport.Write(dataBuff.Bytes()) inside connect (invoked on the transport 'connect' event) returns a non-nil error — connection already closed, reset by peer, or the underlying socket is dead.

Common situations: Server closed the TCP connection immediately after TLS/security negotiation (e.g. NLA required but not supported); firewall or NAT drops the connection mid-handshake; network timeout; server crashed between connect and MCS phase.

Related errors


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