In NETCONF, what do the client and server exchange in their <hello> messages, and how do they settle the protocol version and session-id?
answer
- both speak first
- capability URIs, at least one base
- highest version in common
- only one side numbers the session
basics
~20 sEach NETCONF peer sends a <hello> listing its capabilities as soon as the session opens, without waiting for the other. They use the highest base protocol version both list, or stop; only the server's hello carries the <session-id>.
solid answer
~40 sWhen the NETCONF session opens, **both** peers send a `<hello>` at once; RFC 6241 says a peer **MUST NOT wait** for the other's hello. Each hello lists capability URIs, including at least one base protocol version such as `urn:ietf:params:netconf:base:1.1`. Each side checks for a common version; with none, the session must not continue, and with several, both use the highest. The **server's** hello must carry a `<session-id>`; the client's must not. A server receiving a hello with a session-id terminates the session, and a client receiving a server hello without one terminates it too, without sending `<close-session>`. Watch the two URIs: the element namespace stays `urn:ietf:params:xml:ns:netconf:base:1.0` in every session, while the **capability** `base:1.1` is what selects the version.
code
xml · 8 lines<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<capabilities>
<capability>urn:ietf:params:netconf:base:1.0</capability>
<capability>urn:ietf:params:netconf:base:1.1</capability>
<capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
</capabilities>
<session-id>17</session-id>
</hello>go deeper
Recall that both sides open with a hello listing capabilities, and that the server's hello carries the session ID.
Explain the version rule exactly: compare only the base part, require a common version, use the highest, and know that client and server each enforce the session-id rule by terminating.
Diagnose with it: tell the XML namespace from the base:1.1 capability, read in-bad-hellos when sessions die at start-up, and know that the hello result also fixes the framing on SSH and TLS.
Weigh capability negotiation as an evolution strategy: listing several base versions lets old and new peers coexist, at the cost of any peer that keeps 1.0 also carrying the old end-of-message framing.
## What a hello is A **NETCONF session** starts with a **capabilities exchange**. A **capability** is a URI naming a feature the peer supports: a base protocol version, an optional protocol feature such as the candidate datastore, or a data model. Each peer puts its list inside a `<hello>` element and sends it as the first message of the session. RFC 6241 Section 8.1 defines the rules, and RFC 6242 Section 3.1 applies them to SSH. The hello is **not an RPC**. It has no `message-id`, it is not wrapped in `<rpc>`, and nothing replies to it. It is a one-way announcement from each side. ## Both sides speak first RFC 6241 says each peer sends its hello **as soon as the connection is open** and **MUST NOT wait** to receive the other side's capabilities before sending its own. RFC 6242's example shows the server's hello first, but it adds that both sides send as soon as the subsystem starts, possibly simultaneously. A client that holds its own hello until the server's arrives breaks that rule, even if it usually works because the server sends anyway; a client that expects its hello to be *answered* has misread the protocol. ## What each side puts in it | Element | Server's hello | Client's hello | |---|---|---| | `<capabilities>` with one `<capability>` URI each | **Required** | **Required** | | At least one base version URI | **Required** (RFC 6241: at least `base:1.1`) | **Required** | | Optional capabilities, such as `:candidate` or `:startup` | As supported | As supported | | `<session-id>` | **MUST** be present | **MUST NOT** be present | A peer **MAY** list older base versions too, to show it supports several. Which data-model URIs a server lists, and how a client fetches those models, is a model-discovery question rather than a transport one. ## Agreeing on the base version RFC 6241 Section 8.1 gives the algorithm: 1. Each peer reads the other's capability list. 2. When comparing base version URIs, only the **base part** is compared; any parameters appended to the URI are ignored. 3. If **no** version is common, the peer **MUST NOT continue** the session. 4. If **more than one** version is common, both peers **MUST** use the **highest**. On SSH and TLS the result also picks the **framing**: if both hellos list `:base:1.1`, everything after the hellos uses chunked framing; otherwise the old `]]>]]>` end-of-message framing continues. The hellos themselves always end with `]]>]]>`, because neither side can know the other's version until it has read the other's hello. ## The namespace is not the version Two strings look alike and mean different things: - `urn:ietf:params:xml:ns:netconf:base:1.0` is the **XML namespace** of every NETCONF protocol element. It stays `base:1.0` in a NETCONF 1.1 session. - `urn:ietf:params:netconf:base:1.1` is the **capability URI** that announces protocol version 1.1. So a hello written as `<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">` that lists the `base:1.1` capability is a NETCONF 1.1 hello. Reading the namespace as the version is a common misdiagnosis. ## The session-id rule and its failure paths The **session ID** identifies this session on the server. It is a positive integer; zero is never a session's ID, and the protocol uses it, for example, to report a lock held by something other than a NETCONF session. Later operations refer to it, such as forcibly ending another session or reading who holds a lock. The rules are strict and symmetric: - The **server** MUST include `<session-id>` in its hello. - The **client** MUST NOT include one. - A server that **receives** a hello containing a session-id **MUST terminate** the session. - A client whose received server hello has **no** session-id **MUST terminate** the session, **without first sending** `<close-session>`. On the server, the monitoring module of RFC 6022 (`ietf-netconf-monitoring`) counts these failures in `in-bad-hellos`: sessions silently dropped because of an invalid hello, including one carrying a session-id, a bad namespace or bad capability declarations. `in-sessions` minus `in-bad-hellos` gives the number of correctly started sessions. ## Why the design is this way - **No round trip.** Sending simultaneously costs no extra latency and cannot deadlock. - **Version safety.** Requiring a common version, and the highest one, lets a 1.1 peer keep talking to a peer that also lists 1.0, while refusing to guess when nothing overlaps. - **One numbering authority.** The server owns the session table, so only it issues the ID.
- What must a NETCONF client do if the server's hello has no <session-id>?Terminate the session, and do so without sending <close-session> first (RFC 6241 Section 8.1). A server hello without a session ID is malformed, so the client cannot treat the session as established and has no basis for an orderly NETCONF exit.
- Where can an operator see sessions that failed at the hello stage?In the RFC 6022 monitoring data, the in-bad-hellos counter: sessions silently dropped because an invalid hello arrived, including one with a session-id, a bad namespace or bad capability declarations. Comparing it with in-sessions shows how many sessions started correctly.
- Why do both peers send their hello without waiting for the other?RFC 6241 forbids waiting. Simultaneous sending costs no round trip and cannot deadlock with two peers each waiting for the other to speak first. Each side decides the version, and on SSH or TLS the framing, only after it has both lists.
saying these in an interview costs you the question
- The client waits for the server's hello and then replies to it.
- The client's hello proposes a session-id and the server confirms it.
- A hello in the base:1.0 namespace means the session runs NETCONF 1.0.
- When versions differ, the peers fall back to the lowest one they share.
- A hello is an <rpc> that the other side answers with <rpc-reply>.