shadow1ng/fscan · error
oracle protocol negotiation expected message 1, got %d
Error message
oracle protocol negotiation expected message 1, got %d
What it means
After the connect packet is sent, the Oracle raw protocol handshake expects the server's first protocol negotiation message to start with message type 1. The server sent a different message byte, so the library aborts with the actual value received. This is a guard against talking to something that is not a normal Oracle TNS listener response flow.
Source
Thrown at plugins/services/oracle_raw.go:969
if length > 0 {
_, err = s.getBytes(length)
}
return err
}
func (s *oracleSession) protocolNegotiation() (*oracleTCPNego, error) {
s.reset()
s.putBytes(1, 6, 0)
s.putBytes([]byte("OracleClientGo\x00")...)
if err := s.writeData(); err != nil {
return nil, err
}
msg, err := s.getByte()
if err != nil {
return nil, err
}
if msg != 1 {
return nil, fmt.Errorf("oracle protocol negotiation expected message 1, got %d", msg)
}
proto, err := s.getByte()
if err != nil {
return nil, err
}
if proto != 4 && proto != 5 && proto != 6 {
return nil, errors.New("unsupported oracle server protocol version")
}
if _, err = s.getByte(); err != nil {
return nil, err
}
if _, err = s.getNullTermString(50); err != nil {
return nil, err
}
serverCharset, err := s.getInt(2, false, false)
if err != nil {
return nil, err
}View on GitHub (pinned to 95cc12e753)
Solutions
- Verify the host/port/SID or service name in the connection string points at a real Oracle listener (test with tnsping or lsnrctl status).
- Check whether the listener redirects connections (LOAD_BALANCE/PRECONNECT options) and connect directly to the serving node if redirects are not supported.
- Confirm no firewall/proxy is interposing on the connection; capture the first response bytes to see what the server actually returned.
Example fix
// before ds := "oracle://user:pass@dbhost:1522/SVC" // after (correct listener port verified via lsnrctl status) ds := "oracle://user:pass@dbhost:1521/SVC"
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: confirm a live Oracle listener before opening the app connection
conn, err := net.DialTimeout("tcp", "dbhost:1521", 3*time.Second)
if err != nil { log.Fatal("no listener on port") }
conn.Close() Prevention
- Validate host/port/service in DSNs against lsnrctl status output
- Avoid connecting to ports shared with other services
- Handle listener redirects by connecting to the actual serving node
When it happens
Trigger: oracleRawAuth -> protocolNegotiation reads the first byte after connecting and it is not 1 (e.g. 4 = a redirect/refuse packet, an error packet, or garbage from a non-Oracle service).
Common situations: Connecting to a port that is not an Oracle listener (wrong host/port config); the listener redirects to another node and the client mishandles the redirect; an old Oracle version or intermediary device answering with a different message order; a health-check probe hitting the DB port.
Related errors
- unsupported oracle server protocol version
- oracle advanced negotiation type mismatch: %d
- oracle data type negotiation expected message 2, got %d
- Not a valid license packet
- short oracle accept packet
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/60820258968545cf.
Report an issue: GitHub.