shadow1ng/fscan · error

unexpected connect in auth-only mode

Error message

unexpected connect in auth-only mode

What it means

In NLA auth-only mode the client only performs CredSSP/NLA negotiation and must never complete a full X.224 connection sequence. If the x224 layer signals a 'connect' event (the server accepted and offered a protocol, moving beyond auth-only expectations), the library deliberately aborts with this internal invariant error.

Source

Thrown at libs/grdp/login/screen.go:153

	g.x224 = x224.New(g.tpkt)

	// 设置NLA仅验证模式
	g.tpkt.SetNLAAuthOnly(true)

	// 使用 PROTOCOL_HYBRID (NLA) 协议
	g.x224.SetRequestedProtocol(x224.PROTOCOL_HYBRID)

	// 用于接收结果的通道
	resultChan := make(chan error, 1)

	// 监听错误事件(包括 ErrNLAAuthSuccess)
	g.x224.On("error", func(err error) {
		resultChan <- err
	})

	// 监听连接事件(不应该发生在 auth-only 模式)
	g.x224.On("connect", func(protocol uint32) {
		resultChan <- fmt.Errorf("unexpected connect in auth-only mode")
	})

	// 发起连接
	err = g.x224.Connect()
	if err != nil {
		return false, err
	}

	// 等待结果或超时
	select {
	case err := <-resultChan:
		if err == tpkt.ErrNLAAuthSuccess {
			return true, nil
		}
		return false, err
	case <-time.After(time.Duration(timeout*3) * time.Second):
		return false, fmt.Errorf("NLA auth timeout")
	}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Enable NLA on the target host (System Properties > Remote > 'Allow connections only with NLA') so the auth-only probe stays within CredSSP.
  2. Use a full Client.Login/connect flow instead of NlaAuthOnly if you intend to establish a session.
  3. Check the negotiated protocol in the connect callback; if the server falls back from PROTOCOL_HYBRID, it lacks NLA support.
  4. Treat this as an internal invariant violation and report it if the server does have NLA enabled.
Defensive patterns

Strategy: fallback

Try / catch

ok, err := client.NlaAuthOnly(domain, user, pwd, timeout)
if err != nil && strings.Contains(err.Error(), "unexpected connect in auth-only mode") {
	// server lacks NLA; fall back to full session flow or mark as non-NLA host
	return classifyNonNLAHost(host)
}

Prevention

When it happens

Trigger: Calling NlaAuthOnly and the RDP server responds in a way that advances x224 to a full connect state — e.g. the server skips or accepts NLA negotiation unexpectedly (Protocol fallback to plain RDP security), or a protocol/state bug in the negotiated handshake.

Common situations: Target servers configured without NLA (Encryption Level 'Client Compatible'/'Low'), causing the server to bypass CredSSP and proceed straight to a session connect; older Windows targets with relaxed security policy.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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