shadow1ng/fscan · error
expected oracle data packet, got %d
Error message
expected oracle data packet, got %d
What it means
Session.read reads a packet and, once the buffered data is exhausted, requires the next packet to be a DATA packet. RESEND packets are explicitly unsupported and any other type triggers 'expected oracle data packet, got %d'. It indicates the server sent a control packet where the client expected payload data.
Source
Thrown at plugins/services/oracle_raw.go:337
func (s *oracleSession) reset() {
s.in = nil
s.out.Reset()
s.index = 0
s.summary = nil
}
func (s *oracleSession) read(n int) ([]byte, error) {
for s.index+n > len(s.in) {
p, err := s.readPacket()
if err != nil {
return nil, err
}
if p.typ == oraclePacketResend {
return nil, errors.New("oracle resend is not supported")
}
if p.typ != oraclePacketData {
return nil, fmt.Errorf("expected oracle data packet, got %d", p.typ)
}
}
ret := s.in[s.index : s.index+n]
s.index += n
return ret, nil
}
func (s *oracleSession) putBytes(data ...byte) {
s.out.Write(data)
}
func (s *oracleSession) putString(v string) {
s.putClr([]byte(v))
}
func (s *oracleSession) putInt(v interface{}, size uint8, bigEndian, compress bool) {
num := toInt64(v)
if compress {View on GitHub (pinned to 95cc12e753)
Solutions
- Re-establish the TNS session from scratch — a mid-stream control packet usually invalidates the session state
- If RESEND occurs, the server wants the connect data retransmitted; the lightweight client does not support this, so avoid triggers (unstable network, slow handshake)
- Log the actual packet type to identify which control packet the server sent
- Check for session desync caused by an earlier read error that was ignored
Example fix
// before
if p.typ == oraclePacketResend {
return nil, errors.New("oracle resend is not supported")
}
// after
if p.typ == oraclePacketResend {
return nil, fmt.Errorf("oracle resend requested by server; reconnect required")
} Defensive patterns
Strategy: try-catch
Validate before calling
// before reading data, verify session state is sane
if s.handshakeComplete == false {
return errors.New("session not ready for data reads")
} Type guard
func isDataPacket(p *oraclePacket) bool { return p != nil && p.typ == oraclePacketData } Try / catch
b, err := s.read(n)
if err != nil {
if strings.Contains(err.Error(), "expected oracle data packet") {
// server sent control/resend packet: rebuild the session
return reestablishSession(ctx)
}
return err
} Prevention
- Avoid unstable networks that provoke server RESEND requests (unsupported by the lightweight client)
- Never ignore earlier read errors — desync leads to wrong packet types later
- Log the received packet type to identify server-side control messages
When it happens
Trigger: getByte/getBytes/getInt64/getNullTermString call s.read, the buffer is empty, and the freshly read packet has typ != oraclePacketData (or is a RESEND packet); TestSessionRead covers this.
Common situations: Server requests a resend because it lost handshake state; session desync after an earlier parse error; server rejects the session mid-stream and sends an error/control packet type.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- unexpected oracle packet type %d
- invalid oracle packet length %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/cad46f96ce7298b9.
Report an issue: GitHub.