shadow1ng/fscan · error

unexpected oracle packet type

Error message

unexpected oracle packet type %d

What it means

When the TNS session receives a packet whose type is not Accept, Refuse, or Redirect, connect reports it via 'unexpected oracle packet type %d'. The raw protocol layer only understands these three response types during connection setup, so anything else means the peer is not behaving like an Oracle listener.

Solutions

  1. Verify the target actually runs an Oracle listener on that port
  2. Check for port forwarding/proxy that injects non-TNS bytes
  3. Re-sync the parser — ensure prior reads consumed exactly the packet length (see invalid oracle packet length handling)
  4. Add the unknown type's numeric value to diagnostics when reporting

Example fix

// before
default:
    return fmt.Errorf("unexpected oracle packet type %d", p.typ)
// after
default:
    return fmt.Errorf("unexpected oracle packet type %d (raw % x)", p.typ, p.raw)
Defensive patterns

Strategy: validation

Validate before calling

// pre-verify the port speaks TNS before protocol work
tn, err := net.DialTimeout("tcp", addr, 3*time.Second)
if err != nil { return err }
// optionally send an empty TNS probe and check for a recognizable reply

Type guard

func isKnownOraclePacket(typ byte) bool {
    return typ == oraclePacketAccept || typ == oraclePacketRefuse || typ == oraclePacketRedirect
}

Try / catch

if err := s.connect(ctx, host, port, svc); err != nil {
    if strings.Contains(err.Error(), "unexpected oracle packet type") {
        return ErrNotOracleListener // classify target as non-Oracle, skip
    }
    return err
}

Prevention

When it happens

Trigger: oracleRawAuth -> connect reads a packet after sending the TNS CONNECT data and its type byte is outside the known set (oraclePacketAccept/Refuse/Redirect).

Common situations: Target port is not Oracle (HTTP or SSH server echoing bytes); a proxy answers with its own protocol; corrupt stream desynchronizes packet framing so a payload byte is read as a 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


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

Appendix: source

Thrown at plugins/services/oracle_raw.go:216

		if s.version >= 315 {
			s.sessionDataUnit = binary.BigEndian.Uint32(p.raw[32:36])
			s.transportDataUnit = binary.BigEndian.Uint32(p.raw[36:40])
		}
		if s.transportDataUnit < s.sessionDataUnit {
			s.sessionDataUnit = s.transportDataUnit
		}
		s.acfl0 = p.raw[22]
		s.acfl1 = p.raw[23]
		if s.version >= 315 {
			s.handshakeComplete = true
		}
		return nil
	case oraclePacketRefuse:
		return oracleRefuseError(p.raw)
	case oraclePacketRedirect:
		return errors.New("oracle redirect is not supported by lightweight auth")
	default:
		return fmt.Errorf("unexpected oracle packet type %d", p.typ)
	}
}

func oracleConnectData(host string, port int, serviceName string) string {
	address := fmt.Sprintf("(ADDRESS=(PROTOCOL=tcp)(HOST=%s)(PORT=%d))", host, port)
	connectData := "(CONNECT_DATA=(SERVICE_NAME=" + serviceName + "))"
	return "(DESCRIPTION=" + address + connectData + ")"
}

type oraclePacket struct {
	typ  uint8
	flag uint8
	raw  []byte
	data []byte
}

func (s *oracleSession) readPacket() (*oraclePacket, error) {
	header := make([]byte, 8)

View on GitHub (pinned to 95cc12e753)