shadow1ng/fscan · error

oracle advanced negotiation header mismatch

Error message

oracle advanced negotiation header mismatch

What it means

The Advanced Negotiation (ANO) exchange begins with a fixed magic marker 0xdeadbeef. readANOHeader reads a 4-byte big-endian integer and fails immediately if it does not equal this magic, meaning the server's response stream is not aligned where ANO data is expected.

Source

Thrown at plugins/services/oracle_raw.go:799

}

func (s *oracleSession) writeANOUB2Array(v []int) {
	s.writeANOPacketHeader(10+len(v)*2, 1)
	s.putInt(uint64(0xdeadbeef), 4, true, false)
	s.putInt(3, 2, true, false)
	s.putInt(len(v), 4, true, false)
	for _, n := range v {
		s.putInt(n, 2, true, false)
	}
}

func (s *oracleSession) readANOHeader() (*oracleANOHeader, error) {
	magic, err := s.getInt64(4, false, true)
	if err != nil {
		return nil, err
	}
	if magic != 0xdeadbeef {
		return nil, errors.New("oracle advanced negotiation header mismatch")
	}
	if _, err = s.getInt(2, false, true); err != nil {
		return nil, err
	}
	if _, err = s.getInt(4, false, true); err != nil {
		return nil, err
	}
	count, err := s.getInt(2, false, true)
	if err != nil {
		return nil, err
	}
	if _, err = s.getByte(); err != nil {
		return nil, err
	}
	return &oracleANOHeader{serviceCount: count}, nil
}

func (s *oracleSession) readANOServiceHeader() (int, int, int, error) {

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Verify server Oracle version supports ANO; if not, disable advanced negotiation in connection options if the plugin exposes such a flag
  2. Check that all prior negotiation steps (protocol/charset) succeeded and consumed exactly the expected bytes — a desync here shifts the magic
  3. Capture traffic and compare the ANO exchange against a working client (e.g. sqlplus) from the same host
  4. Report/upstream if the server consistently omits the header despite supporting ANO

Example fix

// before
magic, err := s.getInt64(4, false, true)
if err != nil {
	return nil, err
}
if magic != 0xdeadbeef {
	return nil, errors.New("oracle advanced negotiation header mismatch")
}
// after
magic, err := s.getInt64(4, false, true)
if err != nil {
	return nil, err
}
if magic != 0xdeadbeef {
	return nil, fmt.Errorf("oracle advanced negotiation header mismatch: got %#x", magic)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the target supports ANO by testing a plain login first
if err := testPlainLogin(dsn); err != nil { return err }

Try / catch

_, err := advancedNegotiation(s)
if err != nil && strings.Contains(err.Error(), "advanced negotiation header mismatch") {
	return fallbackWithoutANO(s) // reconnect with ANO disabled, if supported
}

Prevention

When it happens

Trigger: advancedNegotiation() (or TestReadANOHeader/TestReadANOHeaderBadMagic) calls readANOHeader and the next 4 bytes in the buffer are not 0xdeadbeef — the server skipped, re-ordered, or never sent the ANO header.

Common situations: Connecting to an Oracle server version/edition that does not support advanced negotiation; a previous parsing step desynchronized the byte stream; a proxy altering the TNS payload.

Related errors


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