shadow1ng/fscan · error
Unknown data pdu type2 0x%02x
Error message
Unknown data pdu type2 0x%02x
What it means
readDataPDU in libs/grdp/protocol/pdu/data.go dispatches on the share-data header's pduType2 field. When the received slow-path data PDU type2 is not one the library implements (e.g. an unhandled control/server-directory/notification type), it returns this error. It means the server sent a share control/data PDU type this client cannot decode.
Source
Thrown at libs/grdp/protocol/pdu/data.go:480
case PDUTYPE2_CONTROL:
d = &ControlDataPDU{}
case PDUTYPE2_FONTLIST:
d = &FontListDataPDU{}
case PDUTYPE2_SET_ERROR_INFO_PDU:
d = &ErrorInfoDataPDU{}
case PDUTYPE2_FONTMAP:
d = &FontMapDataPDU{}
case PDUTYPE2_SAVE_SESSION_INFO:
glog.Debug("SAVE_SESSION_INFO event triggered, login successful")
d = &SaveSessionInfo{}
default:
err = errors.New(fmt.Sprintf("Unknown data pdu type2 0x%02x", header.PDUType2))
glog.Error(err)
return nil, err
}
err = d.Unpack(r)
if err != nil {
glog.Error("Read data pdu:", err)
return nil, err
}
p := &DataPDU{
Header: header,
Data: d,
}
return p, nil
}
type DataPDUData interface {View on GitHub (pinned to 95cc12e753)
Solutions
- Identify the 0x%02x value and add a case/struct for that PDUTYPE2 in data.go, or change the default branch to skip/ignore unknown data PDUs and continue the session loop
- Disable server features that trigger the exotic PDU (disable session info advertisement, RAIL, status tracking) in the client's capability/negotiation data
- Confirm the stream is aligned — a misparsed earlier PDU shifts bytes so a random byte lands in pduType2; test against a reference client (mstsc) to the same server
- Update grdp to a version with broader PDUTYPE2 coverage
Example fix
// before (data.go readDataPDU)
default:
err = errors.New(fmt.Sprintf("Unknown data pdu type2 0x%02x", header.PDUType2))
glog.Error(err)
return nil, err
// after: tolerate unknown types
default:
glog.Warn("ignoring unknown data pdu type2 0x%02x", header.PDUType2)
return nil, nil Defensive patterns
Strategy: try-catch
Try / catch
pdu, err := session.ReadDataPDU()
if err != nil {
if strings.Contains(err.Error(), "Unknown data pdu type2") {
log.Printf("skipping unsupported PDU: %v", err)
return nil // tolerate and continue session
}
return err
} Prevention
- Disable unneeded server features (RAIL, session redirection, status tracking) in negotiation
- Patch readDataPDU to ignore unrecognized type2 values instead of terminating the session
- Validate stream alignment when multiple parse errors occur in sequence
- Track MS-RDPBCGR PDUTYPE2 values your server infrastructure emits
When it happens
Trigger: During an RDP session, the server sends a slow-path Data PDU whose pduType2 byte is outside the supported set (PDUTYPE2_UPDATE, PDUTYPE2_CONTROL, PDUTYPE2_POINTER, PDUTYPE2_INPUT, PDUTYPE2_SYNCHRONIZE, PDUTYPE2_SAVE_SESSION_INFO, etc.), typically inside readDataPDU invoked by the session read loop.
Common situations: Windows servers emitting optional PDUs (e.g. PDUTYPE2_STATUS_WINDOW_TRACKING, PDUTYPE2_SHUTDOWN_DENIED) the Go client never implemented; stream desynchronization after a previous malformed PDU; connecting to terminal servers with session-redirection or RAIL features enabled.
Related errors
- unsupported Capability type 0x%04x
- Unsupport slow update type 0x%x
- invalid length in Auto-Reconnect packet
- unsupported version of Auto-Reconnect packet
- invalid ber tag
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/2fa974a38d0039bc.
Report an issue: GitHub.