shadow1ng/fscan · error
invalid oracle packet length %d
Error message
invalid oracle packet length %d
What it means
readPacket first reads an 8-byte header, then derives the packet length: 4 bytes big-endian for post-handshake sessions with version >= 315, otherwise 2 bytes. This error is thrown when the derived length is below the minimum viable packet (8) or exceeds the 16MB cap — a framing desync or malicious/garbage stream.
Source
Thrown at plugins/services/oracle_raw.go:245
typ uint8
flag uint8
raw []byte
data []byte
}
func (s *oracleSession) readPacket() (*oraclePacket, error) {
header := make([]byte, 8)
if err := s.readFull(header); err != nil {
return nil, err
}
var length uint32
if s.handshakeComplete && s.version >= 315 {
length = binary.BigEndian.Uint32(header[0:4])
} else {
length = uint32(binary.BigEndian.Uint16(header[0:2]))
}
if length < 8 || length > 16*1024*1024 {
return nil, fmt.Errorf("invalid oracle packet length %d", length)
}
raw := make([]byte, length)
copy(raw, header)
if err := s.readFull(raw[8:]); err != nil {
return nil, err
}
p := &oraclePacket{typ: raw[4], flag: raw[5], raw: raw}
if p.typ == oraclePacketData {
if len(raw) < 10 {
return nil, errors.New("short oracle data packet")
}
p.data = raw[10:]
s.in = append(s.in, p.data...)
}
return p, nil
}
func (s *oracleSession) readFull(buf []byte) error {View on GitHub (pinned to 95cc12e753)
Solutions
- Check whether a prior parse error desynchronized the stream; re-establish the connection rather than continuing to read
- Confirm the peer is an Oracle TNS listener
- Verify the version-based length field selection matches the negotiated packet version
- If legitimate packets exceed 16MB, revisit the cap (unlikely for TNS control packets)
Example fix
// before
if length < 8 || length > 16*1024*1024 {
return nil, fmt.Errorf("invalid oracle packet length %d", length)
}
// after
if length < 8 || length > 16*1024*1024 {
return nil, fmt.Errorf("invalid oracle packet length %d (header % x)", length, header)
} Defensive patterns
Strategy: validation
Validate before calling
func validPacketLength(length uint32) bool {
return length >= 8 && length <= 16*1024*1024
} Type guard
func isValidTNSSession(s *Session) bool { return s != nil && s.version >= 0 } // ensure version negotiated before length parsing Try / catch
pkt, err := s.readPacket()
if err != nil {
if strings.Contains(err.Error(), "invalid oracle packet length") {
return reconnectAndRestart() // framing desynced; session is unrecoverable
}
return err
} Prevention
- After any parse error, discard the session instead of continuing reads
- Match length-field width (2 vs 4 bytes) to the negotiated packet version
- Treat lengths near the 16MB cap as suspicious — TNS control packets are small
When it happens
Trigger: connect or read calls readPacket on a stream where the header bytes are not a real TNS packet header — e.g. after protocol desync or from a non-Oracle peer.
Common situations: Parsing a stream offset by a few bytes after a misread packet; target service is not Oracle; corrupted TCP stream from a flaky link; attacker-supplied oversized length field.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- unexpected oracle packet type %d
- expected oracle data packet, got %d
- invalid oracle integer size %d
- oracle authentication failed
- short oracle accept packet
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/9c94b744c09dda33.
Report an issue: GitHub.