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.

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.

Appendix: 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)