{"record":{"id":"008c2226b4b212b8","repo":"shadow1ng/fscan","slug":"unsupported-capability-type-0x-04x","errorCode":null,"errorMessage":"unsupported Capability type 0x%04x","messagePattern":"unsupported Capability type 0x%04x","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/grdp/protocol/pdu/caps.go","lineNumber":750,"sourceCode":"\t\tc = &DrawGDIPlusCapability{}\n\tcase CAPSETTYPE_BITMAP_CODECS:\n\t\tc = &BitmapCodecsCapability{}\n\tcase CAPSTYPE_BITMAPCACHE_HOSTSUPPORT:\n\t\tc = &BitmapCacheHostSupportCapability{}\n\tcase CAPSETTYPE_LARGE_POINTER:\n\t\tc = &LargePointerCapability{}\n\tcase CAPSTYPE_RAIL:\n\t\tc = &RemoteProgramsCapability{}\n\tcase CAPSTYPE_WINDOW:\n\t\tc = &WindowListCapability{}\n\tcase CAPSETTYPE_COMPDESK:\n\t\tc = &DesktopCompositionCapability{}\n\tcase CAPSETTYPE_SURFACE_COMMANDS:\n\t\tc = &SurfaceCommandsCapability{}\n\tcase CAPSSETTYPE_FRAME_ACKNOWLEDGE:\n\t\tc = &FrameAcknowledgeCapability{}\n\tdefault:\n\t\terr := errors.New(fmt.Sprintf(\"unsupported Capability type 0x%04x\", capType))\n\t\tglog.Error(err)\n\t\treturn nil, err\n\t}\n\tif err := struc.Unpack(capReader, c); err != nil {\n\t\tglog.Error(\"Capability unpack error\", err, fmt.Sprintf(\"0x%04x\", capType), hex.EncodeToString(capBytes))\n\t\treturn nil, err\n\t}\n\tglog.Debugf(\"Capability<%s>: %+v\", c.Type(), c)\n\treturn c, nil\n}\n","sourceCodeStart":732,"sourceCodeEnd":761,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/libs/grdp/protocol/pdu/caps.go#L732-L761","documentation":"readCapability in libs/grdp/protocol/pdu/caps.go parses one TS_CAPABILITYSET entry from a Demand-Active or Confirm-Active PDU. When the 16-bit capabilitySetType is not one of the CAPSETTYPE_* values the library has a struct for, it returns this error instead of guessing at the binary layout. It indicates the remote RDP server advertised a capability set this client does not implement.","triggerScenarios":"Calling grdp's RDP connect/session flow against a server whose Demand-Active (readDemandActivePDU) or Confirm-Active (readConfirmActivePDU) PDU contains a capability set type outside the supported switch (e.g. CAPSETTYPE_MULTIFRAGMENTUPDATE, share, or window-activation caps).","commonSituations":"Connecting to newer Windows servers or hypervisor consoles (Hyper-V/VMWare consoles) that advertise extended capability sets; mismatched security/negotiation settings causing misparse of the capability stream; forked/older grdp not updated for newer MS-RDPBCGR cap types.","solutions":["Capture the printed 0x%04x value and add a matching CAPSETTYPE_* case + struct in caps.go readCapability, or make the default case skip the capability using its length field instead of failing","Connect with client capability negotiation restricted to well-supported caps, or update/pin a grdp version supporting the server's cap sets","Verify the stream is not desynchronized (a wrong capLen earlier in the list makes a later length field read as capType); test against a known-good server to confirm","If you control the fork, log the raw cap bytes (already hex-encoded in the nearby unpack error path) and compare with MS-RDPBCGR to identify the set"],"exampleFix":"// before (caps.go readCapability)\ndefault:\n\terr := errors.New(fmt.Sprintf(\"unsupported Capability type 0x%04x\", capType))\n\tglog.Error(err)\n\treturn nil, err\n// after: skip unknown sets using the already-read length\ndefault:\n\tif _, err := io.ReadFull(r, make([]byte, int(capLen)-4)); err != nil {\n\t\treturn nil, err\n\t}\n\treturn readCapability(r) // next capability in the list","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := client.Connect(addr, opts)\nif err != nil {\n    if strings.Contains(err.Error(), \"unsupported Capability type\") {\n        // fall back to a server profile with restricted caps or report unsupported server\n        return fmt.Errorf(\"server advertises unsupported RDP capability: %w\", err)\n    }\n    return err\n}","preventionTips":["Test against your actual target servers (Windows versions, hypervisor consoles) before rollout","Keep grdp updated for new MS-RDPBCGR capability sets","Patch the default case to skip unknown capability sets by length rather than aborting","Watch for cascading parse errors — they signal stream desync, not a truly unknown cap"],"tags":["rdp","protocol-parsing","unsupported-capability"],"backgroundTag":"unsupported-enum-value","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}