Skip to content

Commit e675eff

Browse files
sleepyStickjyemin
andauthored
DRIVERS-2944 Update handshake spec to allow using OP_MSG exclusively (#1933)
Co-authored-by: Jeff Yemin <jeff.yemin@mongodb.com>
1 parent c9b3ee0 commit e675eff

4 files changed

Lines changed: 133 additions & 21 deletions

File tree

source/message/OP_MSG.md

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,11 @@ The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SH
1717

1818
#### Usage
1919

20-
`OP_MSG` is only available in MongoDB 3.6 (`maxWireVersion >= 6`) and later. MongoDB drivers MUST perform the MongoDB
21-
handshake using `OP_MSG` if an API version was declared on the client.
22-
23-
If no API version was declared, drivers that have historically supported MongoDB 3.4 and earlier MUST perform the
24-
handshake using `OP_QUERY` to determine if the node supports `OP_MSG`. Drivers that have only ever supported MongoDB 3.6
25-
and newer MAY default to using `OP_MSG`.
26-
27-
If the node supports `OP_MSG`, any and all messages MUST use `OP_MSG`, optionally compressed with `OP_COMPRESSED`.
28-
Authentication messages MUST also use `OP_MSG` when it is supported, but MUST NOT use `OP_COMPRESSED`.
20+
All messages, including authentication messages, MUST use `OP_MSG`. Refer to the
21+
[handshake specification](https://github.com/mongodb/specifications/blob/master/source/mongodb-handshake/handshake.md)
22+
for the appropriate use of `OP_MSG`. See also
23+
[OP_COMPRESSED specification](https://github.com/mongodb/specifications/blob/master/source/compression/OP_COMPRESSED.md)
24+
for more details.
2925

3026
#### OP_MSG
3127

@@ -409,6 +405,7 @@ In the near future, this opcode is expected to be extended and include support f
409405

410406
### Changelog
411407

408+
- 2026-06-05: Use OP_MSG for all messages.
412409
- 2024-04-30: Convert from RestructuredText to Markdown.
413410
- 2022-10-05: Remove spec front matter.
414411
- 2022-01-13: Clarify that `OP_MSG` must be used when using stable API

source/mongodb-handshake/handshake.md

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,18 @@ MongoDB uses the `hello` or `isMaster` commands for handshakes and topology moni
4949
preferred command. `hello` must always be sent using the `OP_MSG` protocol. `isMaster` is referred to as "legacy hello"
5050
and is maintained for backwards compatibility with servers that do not support the `hello` command.
5151

52-
If a [server API version](../versioned-api/versioned-api.md) is requested or `loadBalanced: True`, drivers MUST use the
53-
`hello` command for the initial handshake and use the `OP_MSG` protocol. If server API version is not requested and
54-
`loadBalanced: False`, drivers MUST use legacy hello for the first message of the initial handshake with the `OP_QUERY`
55-
protocol (before switching to `OP_MSG` if the `maxWireVersion` indicates compatibility), and include `helloOk:true` in
56-
the handshake request.
52+
Drivers MUST use the `OP_MSG` protocol for all handshakes if their minWireVersion is 6 (MongoDB 3.6) or higher. If a
53+
[server API version](../versioned-api/versioned-api.md) is requested or `loadBalanced: True`, drivers MUST also use the
54+
`hello` command for the initial handshake. If server API version is not requested and `loadBalanced: False`, drivers
55+
MUST use legacy hello for the first message of the initial handshake, and include `helloOk:true` in the handshake
56+
request.
5757

5858
ASIDE: If the legacy handshake response includes `helloOk: true`, then subsequent topology monitoring commands MUST use
5959
the `hello` command. If the legacy handshake response does not include `helloOk: true`, then subsequent topology
6060
monitoring commands MUST use the legacy hello command. See the
6161
[Server Discovery and Monitoring spec](../server-discovery-and-monitoring/server-discovery-and-monitoring-summary.md)
62-
for further information.
62+
for further information. Additionally, note that if the server does not understand `OP_MSG`, the server will close the
63+
socket.
6364

6465
The initial handshake MUST be performed on every socket to any and all servers upon establishing the connection to
6566
MongoDB, including reconnects of dropped connections and newly discovered members of a cluster. It MUST be the first
@@ -80,10 +81,8 @@ conn = Connection()
8081
conn.connect() # Connect via TCP / TLS
8182
if stable_api_configured or client_options.load_balanced:
8283
cmd = {"hello": 1}
83-
conn.supports_op_msg = True # Send the initial command via OP_MSG.
8484
else:
8585
cmd = {"legacy hello": 1, "helloOk": 1}
86-
conn.supports_op_msg = False # Send the initial command via OP_QUERY.
8786
cmd["backpressure"] = True
8887
cmd["client"] = client_metadata
8988
if client_options.compressors:
@@ -99,10 +98,6 @@ if creds:
9998

10099
reply = conn.send_command("admin", cmd)
101100

102-
if reply["maxWireVersion"] >= 6:
103-
# Use OP_MSG for all future commands, including authentication.
104-
conn.supports_op_msg = True
105-
106101
# Store the negotiated compressor, see OP_COMPRESSED spec.
107102
if reply.get("compression"):
108103
conn.compressor = reply["compression"][0]
@@ -564,6 +559,7 @@ support the `hello` command, the `helloOk: true` argument is ignored and the leg
564559

565560
## Changelog
566561

562+
- 2026-06-05: Use OP_MSG for all handshakes.
567563
- 2025-09-04: Clarify that drivers do not append the same metadata multiple times.
568564
- 2025-06-09: Add requirement to allow appending to client metadata after `MongoClient` initialization.
569565
- 2024-11-05: Move handshake prose tests from spec file to prose test file.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
"description": "op_msg not supported",
3+
"schemaVersion": "1.3",
4+
"runOnRequirements": [
5+
{
6+
"minServerVersion": "4.4"
7+
}
8+
],
9+
"createEntities": [
10+
{
11+
"client": {
12+
"id": "setupClient",
13+
"useMultipleMongoses": false
14+
}
15+
},
16+
{
17+
"client": {
18+
"id": "client",
19+
"useMultipleMongoses": false,
20+
"uriOptions": {
21+
"appName": "op-msg-handshake-test",
22+
"serverSelectionTimeoutMS": 500
23+
}
24+
}
25+
},
26+
{
27+
"database": {
28+
"id": "database",
29+
"client": "client",
30+
"databaseName": "test"
31+
}
32+
}
33+
],
34+
"tests": [
35+
{
36+
"description": "server closing connection during initial hello produces an error",
37+
"operations": [
38+
{
39+
"name": "failPoint",
40+
"object": "testRunner",
41+
"arguments": {
42+
"client": "setupClient",
43+
"failPoint": {
44+
"configureFailPoint": "failCommand",
45+
"mode": "alwaysOn",
46+
"data": {
47+
"failCommands": [
48+
"hello",
49+
"isMaster"
50+
],
51+
"appName": "op-msg-handshake-test",
52+
"closeConnection": true
53+
}
54+
}
55+
}
56+
},
57+
{
58+
"name": "runCommand",
59+
"object": "database",
60+
"arguments": {
61+
"commandName": "ping",
62+
"command": {
63+
"ping": 1
64+
}
65+
},
66+
"expectError": {
67+
"errorContains": "connection closed",
68+
"isClientError": false
69+
}
70+
}
71+
]
72+
}
73+
]
74+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
description: "op_msg not supported"
2+
schemaVersion: "1.3"
3+
runOnRequirements:
4+
- minServerVersion: "4.4"
5+
createEntities:
6+
- client:
7+
id: "setupClient"
8+
useMultipleMongoses: false
9+
- client:
10+
id: "client"
11+
useMultipleMongoses: false
12+
uriOptions:
13+
appName: "op-msg-handshake-test"
14+
serverSelectionTimeoutMS: 500
15+
- database:
16+
id: "database"
17+
client: "client"
18+
databaseName: "test"
19+
tests:
20+
# If a server doesn't understand OP_MSG, it will just close the socket.
21+
# This test ensures that the existing socket error is still propagated to the user.
22+
- description: "server closing connection during initial hello produces an error"
23+
operations:
24+
- name: "failPoint"
25+
object: "testRunner"
26+
arguments:
27+
client: "setupClient"
28+
failPoint:
29+
configureFailPoint: "failCommand"
30+
mode: "alwaysOn"
31+
data:
32+
failCommands:
33+
- "hello"
34+
- "isMaster"
35+
appName: "op-msg-handshake-test"
36+
closeConnection: true
37+
- name: "runCommand"
38+
object: "database"
39+
arguments:
40+
commandName: "ping"
41+
command:
42+
ping: 1
43+
expectError:
44+
errorContains: "connection closed"
45+
isClientError: false

0 commit comments

Comments
 (0)