shadow1ng/fscan · error

oracle advanced negotiation type mismatch: %d

Error message

oracle advanced negotiation type mismatch: %d

What it means

During Oracle Advanced Negotiation (ANO/NA), the client reads a packet header and expects a specific packet type (version, status, UB1, string, or bytes). The server returned a different type byte than expected, so the library aborts the handshake and reports the actual type value received. This indicates the server's ANO stream does not match the protocol layout the library implements.

Source

Thrown at plugins/services/oracle_raw.go:840

	subPackets, err := s.getInt(2, false, true)
	if err != nil {
		return 0, 0, 0, err
	}
	errCode, err := s.getInt(4, false, true)
	return serviceType, subPackets, errCode, err
}

func (s *oracleSession) readANOPacketHeader(expectType int) (int, error) {
	length, err := s.getInt(2, false, true)
	if err != nil {
		return 0, err
	}
	typ, err := s.getInt(2, false, true)
	if err != nil {
		return 0, err
	}
	if typ != expectType {
		return 0, fmt.Errorf("oracle advanced negotiation type mismatch: %d", typ)
	}
	return length, nil
}

func (s *oracleSession) readANOServiceData(serviceType, subPackets int) error {
	switch serviceType {
	case 1:
		if _, err := s.readANOVersion(); err != nil {
			return err
		}
		status, err := s.readANOStatus()
		if err != nil {
			return err
		}
		if status == 0xfaff && subPackets > 2 {
			if _, err = s.readANOUB1(); err != nil {
				return err
			}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Bypass proxies/poolers and connect directly to the listener to see if the mismatch disappears.
  2. Check the Oracle server/gateway version and verify the plugin supports it; upgrade the plugin if a newer server is in use.
  3. Disable advanced negotiation/data integrity services (e.g. remove Oracle Network Encryption/Checksumming config in sqlnet) on the server so the simpler handshake is used.
  4. Capture the traffic (tcpdump/Wireshark with TNS decoding) and compare the ANO packet types against what the library expects; file an issue with the observed type number if it looks like a real server variant.

Example fix

// Workaround: force the driver to skip ANO when the server is behind a proxy
// before
connStr := "oracle://user:pass@proxy-host:1521/service"
// after
connStr := "oracle://user:pass@db-host:1521/service" // direct listener connection
Defensive patterns

Strategy: try-catch

Try / catch

if err := db.PingContext(ctx); err != nil {
    if strings.Contains(err.Error(), "advanced negotiation type mismatch") {
        // fall back to direct connection or flag unsupported server topology
    }
}

Prevention

When it happens

Trigger: Any of readANOVersion/readANOStatus/readANOUB1/readANOString/readANOBytes during advancedNegotiation receives an ANO packet whose type field differs from the expected constant (e.g. a 0xDEAD-style marker byte or a service-data packet where a version packet was expected).

Common situations: Connecting through a proxy, load balancer, or connection pooler that mangles or partially consumes ANO packets; non-Oracle or Oracle-Cloud gateways answering the negotiation; a mid-stream desync caused by an earlier parse bug; Oracle server versions that send extra/optional ANO sub-packets in a different order.

Related errors


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