shadow1ng/fscan · error
enumerate size is wrong, get %v, expect 1
Error message
enumerate size is wrong, get %v, expect 1
What it means
After the ENUMERATED tag byte validates, ReadEnumerated reads the BER length. BER ENUMERATED used here must carry exactly one byte of content; any other length means the field is malformed, so the error reports the actual length versus the expected 1.
Source
Thrown at libs/grdp/protocol/t125/ber/ber.go:53
)
func berPC(pc bool) uint8 {
if pc {
return PC_CONSTRUCT
}
return PC_PRIMITIVE
}
func ReadEnumerated(r io.Reader) (uint8, error) {
if !ReadUniversalTag(TAG_ENUMERATED, false, r) {
return 0, errors.New("invalid ber tag")
}
length, err := ReadLength(r)
if err != nil {
return 0, err
}
if length != 1 {
return 0, errors.New(fmt.Sprintf("enumerate size is wrong, get %v, expect 1", length))
}
return core.ReadUInt8(r)
}
func ReadUniversalTag(tag uint8, pc bool, r io.Reader) bool {
bb, _ := core.ReadUInt8(r)
return bb == (CLASS_UNIV|berPC(pc))|(TAG_MASK&tag)
}
func WriteUniversalTag(tag uint8, pc bool, w io.Writer) {
core.WriteUInt8((CLASS_UNIV|berPC(pc))|(TAG_MASK&tag), w)
}
func ReadLength(r io.Reader) (int, error) {
ret := 0
size, _ := core.ReadUInt8(r)
if size&0x80 > 0 {
size = size &^ 0x80View on GitHub (pinned to 95cc12e753)
Solutions
- Capture the server's CONNECT_RESPONSE and verify the enumerated (requestedProtocols/domainSelector) encoding uses 1 content byte
- Check for stream desync — an earlier parse consuming wrong byte counts shifts lengths; fix the earlier parser
- If the server genuinely sends a different length, extend ReadEnumerated to decode variable-length enumerated values
- Retry the connection; transient truncation from network issues can produce bogus lengths
Example fix
// before
if length != 1 {
return 0, errors.New(fmt.Sprintf("enumerate size is wrong, get %v, expect 1", length))
}
// after
if length != 1 {
return 0, fmt.Errorf("enumerate size is wrong, get %v, expect 1", length)
} Defensive patterns
Strategy: try-catch
Validate before calling
// sanity-check the CONNECT_RESPONSE region before parsing
// ensure at least tag+length+1 bytes remain for the enumerated field
if len(buf) < pos+3 { return errors.New("CONNECT_RESPONSE truncated before enumerated field") } Try / catch
v, err := ber.ReadEnumerated(r)
if err != nil {
if strings.Contains(err.Error(), "enumerate size is wrong") {
// desync or nonstandard encoder: dump bytes and resynchronize
}
return err
} Prevention
- Enable debug hex-dumps of CONNECT_RESPONSE for failing servers
- Retry once on transient network errors before surfacing the error
- Verify upstream field parsing consumes exact byte counts
When it happens
Trigger: ReadConnectResponse -> ReadEnumerated when ReadLength returns a value other than 1 (0, 2, or more) for the enumerated field — a malformed or nonstandard CONNECT_RESPONSE.
Common situations: Unusual server implementations encoding the enumerated domain selector with a non-1-byte length; corrupted or truncated responses from flaky networks; protocol desync from earlier skipped bytes.
Related errors
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/d9ba62d5cce017bd.
Report an issue: GitHub.