shadow1ng/fscan · error
Not a valid license packet
Error message
Not a valid license packet
What it means
During the RDP connect sequence, the client received a licensing PDU whose message type is not one it handles (e.g. not PLATFORM_CHALLENGE). The sec layer cannot process the license packet, emits the error on the 'error' channel, and aborts the connection before emitting 'connect'. It indicates the server sent an unexpected licensing message type.
Source
Thrown at libs/grdp/protocol/sec/sec.go:757
goto connect
case lic.ERROR_ALERT:
message := p.LicensingMessage.(*lic.ErrorMessage)
glog.Info("sec ERROR_ALERT and ErrorCode:", message.DwErrorCode)
if message.DwErrorCode == lic.STATUS_VALID_CLIENT && message.DwStateTransaction == lic.ST_NO_TRANSITION {
goto connect
}
goto retry
case lic.LICENSE_REQUEST:
glog.Info("sec LICENSE_REQUEST")
c.sendClientNewLicenseRequest(p.LicensingMessage.([]byte))
goto retry
case lic.PLATFORM_CHALLENGE:
glog.Info("sec PLATFORM_CHALLENGE")
c.sendClientChallengeResponse(p.LicensingMessage.([]byte))
goto retry
default:
glog.Error("Not a valid license packet")
c.Emit("error", errors.New("Not a valid license packet"))
return
}
connect:
c.transport.On("sec", c.recvData)
c.Emit("connect", c.clientData[0].(*gcc.ClientCoreData), c.userId, c.channelId)
return
retry:
c.transport.Once("sec", c.recvLicenceInfo)
return
}
func (c *Client) sendClientNewLicenseRequest(data []byte) {
var req lic.ServerLicenseRequest
struc.Unpack(bytes.NewReader(data), &req)
var sc gcc.ServerCertificateView on GitHub (pinned to 95cc12e753)
Solutions
- Identify the server product; if it is xrdp/FreeRDP-based, update the server or grdp to a version handling its license PDU type
- Capture the licensing PDU (e.g. Wireshark with RDP decryption) and add a case for the received message type in the license switch, treating it like PLATFORM_CHALLENGE or ignoring it
- Try disabling NLA/licensing-sensitive negotiation (set security level to standard RDP or TLS-only) so the server sends a simpler license flow
- Verify you are actually talking to an RDP server on that port and not another service that emits garbage in the license slot
Example fix
// before
default:
glog.Error("Not a valid license packet")
c.Emit("error", errors.New("Not a valid license packet"))
return
// after
case lic.LICENSE_VALID_CLIENT, lic.NEW_LICENSE:
glog.Info("sec: license accepted, continuing")
goto retry
default:
glog.Errorf("Not a valid license packet: type %v", p.LicensingMessage)
c.Emit("error", errors.New("Not a valid license packet"))
return Defensive patterns
Strategy: try-catch
Validate before calling
// before connecting, verify the server speaks RDP
conn, _ := net.DialTimeout("tcp", host+":3389", 5*time.Second)
// X.224 negotiation completes only against a real RDP endpoint; also ensure server version supports this client's license handling
_ = conn Try / catch
client.On("error", func(err error) {
if strings.Contains(err.Error(), "Not a valid license packet") {
// fall back: retry with different requestedProtocols or flag server for manual review
}
}) Prevention
- Pin the server type you support (xrdp/Windows) and test license negotiation against it in CI
- Listen on the client's 'error' event and log the server product/version for triage
- Capture a known-good license PDU trace to diff against failures
When it happens
Trigger: Calling client.Connect()/NewClient against an RDP server whose licensing PDU uses a message type other than PLATFORM_CHALLENGE (e.g. valid-client license, error alert, or a malformed/garbage packet landing in the license switch's default branch).
Common situations: Connecting to non-Windows or partially implemented RDP servers (xrdp, FreeRDP-based gateways, VNC-over-RDP bridges) that send licensing data this library doesn't understand; middleboxes/proxies corrupting the license PDU; targeting servers that skip standard licensing negotiation.
Related errors
- NODE_RDP_PROTOCOL_PDU_SEC_BAD_LICENSE_HEADER
- Unsupport FastPathPDU type 0x%x
- Unknown FastPathPDU type 0x%x
- failed to get server public key
- NODE_RDP_PROTOCOL_T125_MCS_WAIT_CHANNEL_JOIN_CONFIRM
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/3103ef6c01923010.
Report an issue: GitHub.