{"record":{"id":"cad46f96ce7298b9","repo":"shadow1ng/fscan","slug":"expected-oracle-data-packet-got-d","errorCode":null,"errorMessage":"expected oracle data packet, got %d","messagePattern":"expected oracle data packet, got (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/oracle_raw.go","lineNumber":337,"sourceCode":"\nfunc (s *oracleSession) reset() {\n\ts.in = nil\n\ts.out.Reset()\n\ts.index = 0\n\ts.summary = nil\n}\n\nfunc (s *oracleSession) read(n int) ([]byte, error) {\n\tfor s.index+n > len(s.in) {\n\t\tp, err := s.readPacket()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif p.typ == oraclePacketResend {\n\t\t\treturn nil, errors.New(\"oracle resend is not supported\")\n\t\t}\n\t\tif p.typ != oraclePacketData {\n\t\t\treturn nil, fmt.Errorf(\"expected oracle data packet, got %d\", p.typ)\n\t\t}\n\t}\n\tret := s.in[s.index : s.index+n]\n\ts.index += n\n\treturn ret, nil\n}\n\nfunc (s *oracleSession) putBytes(data ...byte) {\n\ts.out.Write(data)\n}\n\nfunc (s *oracleSession) putString(v string) {\n\ts.putClr([]byte(v))\n}\n\nfunc (s *oracleSession) putInt(v interface{}, size uint8, bigEndian, compress bool) {\n\tnum := toInt64(v)\n\tif compress {","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/oracle_raw.go#L319-L355","documentation":"Session.read reads a packet and, once the buffered data is exhausted, requires the next packet to be a DATA packet. RESEND packets are explicitly unsupported and any other type triggers 'expected oracle data packet, got %d'. It indicates the server sent a control packet where the client expected payload data.","triggerScenarios":"getByte/getBytes/getInt64/getNullTermString call s.read, the buffer is empty, and the freshly read packet has typ != oraclePacketData (or is a RESEND packet); TestSessionRead covers this.","commonSituations":"Server requests a resend because it lost handshake state; session desync after an earlier parse error; server rejects the session mid-stream and sends an error/control packet type.","solutions":["Re-establish the TNS session from scratch — a mid-stream control packet usually invalidates the session state","If RESEND occurs, the server wants the connect data retransmitted; the lightweight client does not support this, so avoid triggers (unstable network, slow handshake)","Log the actual packet type to identify which control packet the server sent","Check for session desync caused by an earlier read error that was ignored"],"exampleFix":"// before\nif p.typ == oraclePacketResend {\n    return nil, errors.New(\"oracle resend is not supported\")\n}\n// after\nif p.typ == oraclePacketResend {\n    return nil, fmt.Errorf(\"oracle resend requested by server; reconnect required\")\n}","handlingStrategy":"try-catch","validationCode":"// before reading data, verify session state is sane\nif s.handshakeComplete == false {\n    return errors.New(\"session not ready for data reads\")\n}","typeGuard":"func isDataPacket(p *oraclePacket) bool { return p != nil && p.typ == oraclePacketData }","tryCatchPattern":"b, err := s.read(n)\nif err != nil {\n    if strings.Contains(err.Error(), \"expected oracle data packet\") {\n        // server sent control/resend packet: rebuild the session\n        return reestablishSession(ctx)\n    }\n    return err\n}","preventionTips":["Avoid unstable networks that provoke server RESEND requests (unsupported by the lightweight client)","Never ignore earlier read errors — desync leads to wrong packet types later","Log the received packet type to identify server-side control messages"],"tags":["oracle","tns","protocol-violation"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}