shadow1ng/fscan · error
Unknown FastPathPDU type 0x%x
Error message
Unknown FastPathPDU type 0x%x
What it means
The default branch of the fast-path update switch in pdu/data.go fires when the update code from the server is not any known FASTPATH_UPDATETYPE_* value. The library logs a debug line and returns 'Unknown FastPathPDU type 0x%x' because the PDU cannot be classified or decoded.
Source
Thrown at libs/grdp/protocol/pdu/data.go:930
// 绘图指令,认证检测不需要处理
return nil, errors.New(fmt.Sprintf("Unsupport FastPathPDU type 0x%x", code))
case FASTPATH_UPDATETYPE_BITMAP:
d = &FastPathBitmapUpdateDataPDU{}
case FASTPATH_UPDATETYPE_PALETTE:
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
case FASTPATH_UPDATETYPE_SURFCMDS:
//d = &FastPathSurfaceCmds{}
case FASTPATH_UPDATETYPE_PTR_NULL:
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
case FASTPATH_UPDATETYPE_PTR_POSITION:
case FASTPATH_UPDATETYPE_COLOR:
//d = &FastPathColorPdu{}
case FASTPATH_UPDATETYPE_CACHED:
case FASTPATH_UPDATETYPE_POINTER:
case FASTPATH_UPDATETYPE_LARGE_POINTER:
default:
glog.Debugf("Unknown FastPathPDU type 0x%x", code)
return f, errors.New(fmt.Sprintf("Unknown FastPathPDU type 0x%x", code))
}
if d != nil {
err = d.Unpack(r)
if err != nil {
//glog.Error("Unpack:", err)
return nil, err
}
} else {
return nil, errors.New(fmt.Sprintf("Unsupport FastPathPDU type 0x%x", code))
}
f.Data = d
return f, nil
}
type ShareControlHeader struct {
TotalLength uint16 `struc:"little"`
PDUType uint16 `struc:"little"`View on GitHub (pinned to 95cc12e753)
Solutions
- Update the grdp library to a version supporting the newer FastPath update types.
- Log/inspect the code value in the debug output to identify what the server is sending, then add a case for that constant in parseFastPathUpdate.
- Verify the stream is not desynchronized: check that preceding PDU parsing consumed exactly the right number of bytes.
- If the type is benign for your use case, change the default branch to skip instead of erroring.
Example fix
// before (data.go ~930)
default:
glog.Debugf("Unknown FastPathPDU type 0x%x", code)
return f, errors.New(fmt.Sprintf("Unknown FastPathPDU type 0x%x", code))
// after
default:
glog.Warnf("skipping unknown FastPathPDU type 0x%x", code)
return f, nil Defensive patterns
Strategy: try-catch
Try / catch
client.On("error", func(err error) {
if strings.Contains(err.Error(), "Unknown FastPathPDU type") {
glog.Warn("unknown fast-path update from server: ", err)
return
}
glog.Error("rdp error: ", err)
}) Prevention
- Keep the grdp library updated for newer server update types
- Watch debug logs for the 0x%x code to identify unhandled server types
- Validate the stream isn't desynchronized after any parse error
When it happens
Trigger: Receiving a fast-path update PDU whose type byte falls outside the implemented set (ORDERS, BITMAP, PALETTE, SYNCHRONIZE, SURFCMDS, CACHED, POINTER, LARGE_POINTER) — e.g. a reserved/future update type or corrupted stream bytes misaligned so the type nibble is wrong.
Common situations: Connecting to a newer Windows/terminal server using an update type this grdp version doesn't know; stream desynchronization from an earlier parse bug making garbage bytes look like an update header; testing against non-MS RDP servers with proprietary update codes.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Unsupport FastPathPDU type 0x%x
- NODE_RDP_PROTOCOL_PDU_SEC_BAD_LICENSE_HEADER
- Not a valid license packet
- unsupported Capability type 0x%04x
- Unknown data pdu type2 0x%02x
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/0332136143eef732.
Report an issue: GitHub.