shadow1ng/fscan · error

short oracle data packet

Error message

short oracle data packet

What it means

readPacket parses a raw Oracle Net (TNS) packet from the wire. When the packet type is DATA (0x00), the data payload is expected to start at offset 10, so any DATA packet shorter than 10 bytes cannot carry a payload and this library rejects it rather than returning a corrupted packet. This indicates a truncated or malformed packet from the server or an intermediary.

Source

Thrown at plugins/services/oracle_raw.go:255

	}
	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 {
	if s.timeout > 0 {
		_ = s.conn.SetReadDeadline(time.Now().Add(s.timeout))
	}
	_, err := io.ReadFull(s.conn, buf)
	return err
}

func (s *oracleSession) writeRaw(ctx context.Context, buf []byte) error {
	if deadline, ok := ctx.Deadline(); ok {
		_ = s.conn.SetWriteDeadline(deadline)

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Verify network path stability between client and DB host (no proxy truncating TNS traffic); test with a direct connection to the listener host:port
  2. Confirm the DSN points to a real Oracle listener port, not an HTTP or other service
  3. Retry the connection; if intermittent, investigate MTU/VPN/firewall issues dropping tail bytes
  4. Update the plugin and Oracle server/listener versions and retest; if reproducible on a healthy path, report with a tcpdump capture

Example fix

// before
if p.typ == oraclePacketData {
	if len(raw) < 10 {
		return nil, errors.New("short oracle data packet")
	}
	p.data = raw[10:]
}
// after
if p.typ == oraclePacketData {
	if len(raw) < 10 {
		return nil, fmt.Errorf("short oracle data packet: got %d bytes", len(raw))
	}
	p.data = raw[10:]
}
Defensive patterns

Strategy: retry

Validate before calling

// sanity-check reachability before opening the Oracle session
conn, err := net.DialTimeout("tcp", host+":"+port, 5*time.Second)
if err != nil { return err }
conn.Close()

Try / catch

for attempt := 0; attempt < 3; attempt++ {
	session, err := connect(dsn)
	if err != nil && strings.Contains(err.Error(), "short oracle data packet") {
		time.Sleep(time.Duration(attempt+1) * time.Second)
		continue
	}
	return session, err
}
return nil, errors.New("connection repeatedly returned truncated oracle packets")

Prevention

When it happens

Trigger: A DATA-type oracle packet arrives whose total length is < 10 bytes during connect() or any read() that refills the session buffer; typically the TCP stream returned a header-only or truncated frame.

Common situations: Unstable network links or proxy/LB idle timeouts slicing TNS frames; a middlebox misinterpreting the Oracle wire protocol; connecting to a non-Oracle service that echoes short frames; server crash mid-response.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/365041d31c1e8ce2. Report an issue: GitHub.