ginuerzh/gost · error
bad tls data len
Error message
bad tls data len
What it means
Parse of a TLS obfuscation header failed because the parsed record length exceeds maxTLSDataLen. The library reads the 2-byte TLS record length field and rejects values larger than the allowed maximum, since such a record cannot be a valid TLS handshake/record emitted by the obfuscation protocol. This guards against malformed or hostile streams masquerading as TLS records.
Source
Thrown at obfs.go:323
0x009e, 0xc024, 0xc028, 0x006b, 0xc023, 0xc027, 0x0067, 0xc00a,
0xc014, 0x0039, 0xc009, 0xc013, 0x0033, 0x009d, 0x009c, 0x003d,
0x003c, 0x0035, 0x002f, 0x00ff,
}
compressionMethods = []uint8{0x00}
algorithms = []uint16{
0x0601, 0x0602, 0x0603, 0x0501, 0x0502, 0x0503, 0x0401, 0x0402,
0x0403, 0x0301, 0x0302, 0x0303, 0x0201, 0x0202, 0x0203,
}
tlsRecordTypes = []uint8{0x16, 0x14, 0x16, 0x17}
tlsVersionMinors = []uint8{0x01, 0x03, 0x03, 0x03}
ErrBadType = errors.New("bad type")
ErrBadMajorVersion = errors.New("bad major version")
ErrBadMinorVersion = errors.New("bad minor version")
ErrMaxDataLen = errors.New("bad tls data len")
)
const (
tlsRecordStateType = iota
tlsRecordStateVersion0
tlsRecordStateVersion1
tlsRecordStateLength0
tlsRecordStateLength1
tlsRecordStateData
)
type obfsTLSParser struct {
step uint8
state uint8
length uint16
}
type obfsTLSConn struct {View on GitHub (pinned to a33fdbf4c9)
Solutions
- Verify both endpoints run the same obfs protocol/version and the remote actually speaks the TLS-obfuscation format
- Check the connection for corruption/reordering (unreliable transport) that shifts the parse state
- Re-sync or restart the stream; once the state machine is misaligned, re-establish the connection
- If you control the peer, ensure records are capped at maxTLSDataLen before sending
Example fix
// before: parsing arbitrary bytes that are not obfs-TLS
node, err := obfs.Parse(rawStream)
// after: validate the first record header length before parsing
if binary.BigEndian.Uint16(raw[3:5]) > maxTLSDataLen {
return fmt.Errorf("stream is not valid obfs-tls traffic")
}
node, err := obfs.Parse(raw) Defensive patterns
Strategy: validation
Validate before calling
if len(raw) >= 5 && binary.BigEndian.Uint16(raw[3:5]) > maxTLSDataLen {
return errors.New("invalid obfs-tls record length")
} Prevention
- Confirm both peers run the same obfs version
- Check transport integrity (no reordering/truncation)
- Re-establish the stream after any parse failure
When it happens
Trigger: Calling Parse on a byte stream whose TLS record header carries a length field > maxTLSDataLen (checked in the state machine at obfs.go:389 when r.length is read). Typically happens when the peer is not sending the expected TLS-obfuscated traffic or the stream is corrupted mid-record.
Common situations: Pointing an obfs client at a plain TLS server (raw TLS records may exceed the crafted maximum), byte loss/corruption in the tunnel causing misaligned parsing, or a version mismatch between obfs endpoints.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
AI-assisted analysis of ginuerzh/gost@a33fdbf4c9 (2026-09-02).
Data as JSON: /api/errors/a21f21baad29c113.
Report an issue: GitHub.