Skip to content

What Just Happened: naming the drop

S5·E1Three nights of drops nobody can name · Customer data hall, 02:10, night three of a stalled acceptance run

S5·E1Apply~30 minsources checked todaylab mutates hardwareverified against Cumulus Linux 5.18 WJH, What's New and New/Removed NVUE Commands pages; NetQ 5.1 WJH and gNMI pages — research fetched 2026-09-07, NetQ 5.1 What's New re-fetched 2026-09-07

Builds on: Playbook: 'RoCE is slow'

Before you read: what do you already know?

3 quick questions. Wrong answers are fine and expected; trying first makes the lesson stick.

After this lesson you can

  • Distinguish the WJH service from the WJH agent and name which one a given deployment must disable.
  • Configure a WJH channel with a trigger, a drop filter and an aggregation window using the 5.18 NVUE surface.
  • Read `nv-wjh-cli` and `netq show wjh-drop` output and classify each event by category, drop-reason id range and severity.
  • Diagnose the four documented reasons a WJH deployment reports nothing.

Episode 1 — Three nights of drops nobody can name

The situation · Customer data hall, 02:10, night three of a stalled acceptance run

The night-shift operator calls at 02:10 because he has run out of things to label. A training job on Pod B has stalled three nights running, always in the same phase, and Friday is the acceptance re-test that releases the rest of the customer’s order. He has a terminal open on leaf07 with tcpdump running on the port the rank-0 host is cabled to, and it shows nothing at all. Interface discards on that port climb through every run. The customer’s network lead is on the call too, notebook open at page three, and what she wants is not a theory.

You say the quiet thing first, because it is why three nights were wasted: on a Cumulus switch tcpdump captures only control-plane traffic to and from the CPU, not the data plane, so a forwarding drop leaves no trace in a capture.[7] WJH, SPAN and telemetry are the data-plane answers.[7]

That gap is the reason the feature exists. A discard counter counts; it cannot explain. What Just Happened is the ASIC reporting why it discarded a frame — a service that diagnoses drops locally across layer 1, layer 2, layer 3, tunnels, buffers and ACLs, plus an agent that streams the same contextual telemetry off-box to NetQ.[1]

The operator’s runbook says what-just-happened poll. On this 5.18 box the unit is nv-wjh.service and the CLI is nv-wjh-cli.[1]

A counter tells you that something died; only WJH tells you what killed it.

Start with which of those two components this switch is actually running.

1Two components with one name

What Just Happened is not one thing. Cumulus Linux ships a WJH agent that streams detailed contextual telemetry off the switch to NetQ, and a WJH service that diagnoses dropped packets locally across layer 1, layer 2, layer 3, tunnels, buffers and ACLs.[1] Which one a site runs decides every troubleshooting step afterwards, because the two cannot both own the drop-capture path.[1]

The reason this matters more on a switch than on a server: tcpdump on a Cumulus switch captures only control-plane traffic to and from the CPU, not the data plane.[7] A server engineer’s reflex — capture the interface and look — returns nothing about a forwarding drop. WJH, SPAN and telemetry are the data-plane answers.[7]

Names changed under people. On Cumulus Linux 5.18 and later the systemd unit is nv-wjh.service and the local CLI is nv-wjh-cli; older runbooks and knowledge-base articles say what-just-happened poll, which does not exist on a 5.18 box.[1] Cumulus Linux 5.18.0 also moved WJH filtering and threshold controls into NVUE and made WJH and gNMI subscriptions able to run at the same time, which they previously could not.[4][6]

Symptom:0 / 7 answered
On-box — local diagnosis (nv / Linux CLI)Streaming off-box — sampled or probedDestinationsYour OTLP collectorgRPC 8443 by default · or local JSON on the switchWhat Just Happenednv-wjh-cli · uses a SPAN destinationForwarding resourcescl-resource-query · ASIC resourceLink and opticsnv show interface --view berping · traceroute · tcpdumpand /var/log/switchd.logOTLP exportstat groups, 1 s floorHigh-frequency telemetry100-12,750 microsecondsLatency measurementprobes, per traffic classgNMI streamingNetQ agent, port 9339NetQ 5.1netq check · show · trace — the only cross-switch view

Click a tool, or tab to it and press Enter. Dashed edge: WJH streamed through the NetQ agent instead of read locally.

Symptom

An application reports loss. Interface discard counters move, but nothing says why.

Commit first: pick the surface you would reach for. The map stays quiet until you do.

Pick a symptom, then a tool. Every panel gives the exact command, the sampling or export constraint, the ASIC floor, and what the tool will not answer.

Commit to a tool for 'silent drops' before the map reveals anything, then read the constraint panel.

2Configuring a channel: trigger, filter, aggregation

A channel is the unit of configuration. You create one and attach a trigger:

nv set system wjh channel <name> trigger <type>
nv config apply

Trigger types are l1, l2, l3, tunnel, buffer and acl.[1] Two constraints bite immediately: channel names must be 4 to 16 characters, and each trigger can be enabled on only one channel — so you cannot have a buffer channel per tenant.[1]

Filtering narrows what a channel records:

nv set system wjh channel <id> drop-filter <filter-id> drop-type <type> drop-reason <reason>
nv set system wjh channel <id> drop-filter <filter-id> drop-type <type> severity <level>
nv set system wjh channel <id> drop-filter <filter-id> ip <address>
nv unset system wjh channel <id> drop-filter <filter-id>
nv show system wjh channel <id> drop-filter

[1] Aggregation controls how much the switch summarizes before you read it: nv set system wjh channel <id> polling-interval <5-300> in seconds and nv set system wjh channel <id> aggregate-cache-size <500-5000>.[1] On a busy AI fabric the cache size is the knob that decides whether a burst of identical drops evicts everything else.

Buffer channels can carry thresholds so the channel reports congestion and latency events rather than only discards:

nv set system wjh channel <id> buffer-threshold latency    tc <class> interface <ports> high <ms>
nv set system wjh channel <id> buffer-threshold congestion tc <class> interface <ports> high <percent>
nv show system wjh channel <id> buffer-threshold

[1] Spectrum-6 does not support latency thresholds — on an SN6000-class leaf the congestion form is the one that works.[1]

3Reading it: on-box, and through NetQ

On the switch the three display buffers map to the three questions you ask:

nv show system wjh packet-buffer      # individual drops
nv show system wjh aggregate-buffer   # aggregated events
nv show system wjh l1-buffer          # layer 1 events
nv show system wjh channel            # all channels
nv action export system wjh packet-buffer [no-metadata]   # to PCAP

[1] The Linux form is nv-wjh-cli poll --data <drops|aggregates|l1> --output-type <table|json|pcap> [--channels <list>] [--no-metadata], plus nv-wjh-cli poll dump.[1] PCAP files land in /var/run/nv-wjh/ and diagnostics dumps in /var/log/nv-wjh/diags-dump/<timestamp>.[1]

The categories are what make the output worth reading. L1: link training failure, port state changes, symbol and CRC errors. L2: MLAG isolation, VLAN mismatch, spanning-tree filtering, loopback detection, multicast source MAC. L3/Router: non-routable packets, blackhole routes, unresolved neighbors, loopback and multicast IPs, TTL exhaustion, MTU violations. Tunnel: overlay MAC issues, decapsulation errors, encapsulation isolation. Buffer: tail drop, WRED, congestion thresholds, latency thresholds. ACL: ingress and egress port or router ACL denials.[1]

Through NetQ the same data arrives centrally. Enable it with sudo netq config add agent wjh then sudo netq config restart agent; WJH itself “is enabled by default on NVIDIA Spectrum switches running Cumulus Linux 4.4.0 or later”.[2] Read it with netq [<hostname>] show wjh-drop [severity <sev>] [details] [between <t1> and <t2>] [around <t>] [json], and filter the detailed per-type form by ingress-port, severity, reason, src-ip, dst-ip, proto, src-port, dst-port, src-mac, dst-mac, egress-port, traffic-class, rule-id-acl or vlan.[2] The aggregate output is a six-row table you should be able to read at a glance:

Drop type          Aggregate Count
L1                 560
Buffer             224
Router             144
L2                 0
ACL                0
Tunnel             0

[2] With details the reasons appear: WRED, Blackhole route, Packet Latency Threshold Crossed, Port TC Congestion Threshold, Oper down.[2]

When WJH is streamed over gNMI the reasons arrive as numeric ids, and the ranges are the fastest way to classify a stream you did not generate: L1 10021-10031, L2 201-210, Router 301-327, Tunnel 402-404, ACL 601-604, Buffer 503-506, each carrying a severity of Notice, Warning or Error.[3] The models are nvidia-if-wjh-drop-aggregate for aggregated drops and nvidia-if-ethernet-ext for PFC, WRED, ACL and buffer drop counters; the reason mapping file on the switch is /usr/etc/wjh_lib_conf.xml.[3]

4Why WJH reports nothing

Four documented causes, in the order they are worth checking.

  1. Wrong name. On 5.18 the unit is nv-wjh.service and the CLI is nv-wjh-cli. A runbook that calls what-just-happened poll fails, and a monitoring check that watches the old unit reports the service down forever.[1]

  2. The NetQ agent owns WJH. When the NVIDIA NetQ agent is used for WJH, the local WJH service must be disabled:

    nv set system wjh state disabled
    sudo systemctl disable nv-wjh && sudo systemctl stop nv-wjh

    [1] Both running is a documented conflict, not a bug.[1]

  3. ASIC floor. Buffer packet-drop monitoring requires Spectrum-2 or later, and WJH uses a SPAN destination, so it cannot exceed the switch ASIC’s SPAN limits.[1] On a box already using its SPAN resources for a mirror session, a buffer channel is competing for them.

  4. The panel moved. NetQ 5.1 removed L1 frame error events (symbol and CRC) from the WJH dashboard; the Link Health view retains those counters.[5] An operator watching the old panel after an upgrade sees a regression that is a relocation.[5]

From a raw aggregate to a one-line root cause

A leaf running Cumulus Linux 5.18.1 with two channels — l3drops (trigger l3) and bufdrops (trigger buffer) — during a training-job complaint.

  1. Confirm the channels exist and the triggers are where you think: nv show system wjh channel. Expected: two rows, each with one trigger, no trigger listed twice — a trigger can be on only one channel.[1]
  2. Pull aggregates as JSON so you can filter them: nv-wjh-cli poll --data aggregates --output-type json --channels bufdrops.[1]
  3. Classify by category first, not by header. Buffer reasons are ids 503-506; Router reasons are 301-327.[3]
  4. Suppose the top three rows are: Buffer / WRED / 18,400 events on swp17; Buffer / Port TC Congestion Threshold / 900 on swp17; Router / Blackhole route / 12 on swp3.[2]
  5. Root cause lines: WRED on one uplink at that volume is ECN doing its job or a threshold set too low — cross-check nv show interface swp17 counters qos egress-queue-stats for WRED drops on the RoCE traffic class before you touch anything. The congestion-threshold events are the same event seen through the threshold you configured. The dozen blackhole-route events are unrelated and belong in a different ticket.[1][2]
  6. If you need packets rather than counts, narrow first with a drop filter, then nv action export system wjh packet-buffer and open the PCAP from /var/run/nv-wjh/.[1]

04:00 — the drop has a name

How it ended

By 04:00 leaf07 carries two channels — one on l3, one on buffer — staged together and applied once.[1] The aggregate view names the fault: WRED on a single uplink, the congestion-threshold events you configured beside it, and a dozen blackhole-route entries that belong to a different ticket entirely.[2] The L1 errors that vanished from the customer’s NetQ dashboard at 5.1 were relocated into the Link Health view, not lost.[5]

What you say to the operator, who is already printing a label for that uplink: your discards were never mysterious, they were unnamed. Then the network lead writes leaf07 on page three and asks the question that ends the night — if this leaf was wrong, how do you know the other thirty-one are right?

Lab

Mutating steps ahead. Needs a maintenance window, out-of-band access (BMC/iDRAC/rshim console) and a rollback path. Record the pre-flight inventory before changing anything. Never on a production host.

Pre-flight inventory on the Dell lab hosts before anything else: ip -br link, ethtool -i <ifname> for each ConnectX/BlueField-3 port, and sudo mst start && flint -d /dev/mst/<dev> q for firmware. Save the output; it is the baseline for every later step.

  1. Read-only, host side. Collect the drop evidence a host can produce: ethtool -S <ifname> | grep -Ei 'discard|error|drop|pause' and netstat -s. Expected: counters that go up during a load test.[7]

  2. Run a load that produces discards (many-to-one ib_write_bw from two senders into one receiver), then re-read the same counters. Record the deltas.

  3. Write the comparison that is the point of this lab: for each host counter, state the question it answers and the question it cannot. A host discard counter gives a port and a count; WJH gives the reason and the ingress port on the switch. Neither replaces the other, and on a switch tcpdump gives you neither because it sees only control-plane traffic to and from the CPU.[7]

  4. Optional, customer or partner lab with a Spectrum-2 or later leaf — mutating. Before the change: nv config save and nv config show -o commands > wjh-pre.conf off-box.[8] Then:

    nv set system wjh channel bufdrops trigger buffer
    nv set system wjh channel bufdrops polling-interval 30
    nv config apply --confirm 5

    Confirm within the window if the box is healthy; if it is not, do nothing and the switch rolls back automatically.[8] Rollback: nv unset system wjh channel bufdrops then nv config apply, or restore the saved command file with nv config replace wjh-pre.conf followed by nv config apply.[1][8]

  5. Optional, same leaf: generate congestion, then nv show system wjh aggregate-buffer and nv action export system wjh packet-buffer, and copy the PCAP from /var/run/nv-wjh/ to your laptop to open locally.[1] Rollback: as step 4; the export itself changes no configuration.

  6. If the leaf runs a NetQ agent, do not enable the local service at all — check first with netq config show agent and, if the agent does WJH, leave nv set system wjh state disabled in place and read the data with netq show wjh-drop details instead.[1][2]

Retrieval check

10 questions from memory. Answer before looking anything up; misses become flashcards.

Explain it to a Dell SE

Explain to a Dell platform engineer, in four sentences, what WJH tells them that an interface discard counter does not — and what has to be true on the switch for it to say anything at all.

14 flashcards for this lesson — 0 in deck. Spaced review lives at /review.

Sources

Facts in this lesson were checked against Cumulus Linux 5.18 WJH, What's New and New/Removed NVUE Commands pages; NetQ 5.1 WJH and gNMI pages — research fetched 2026-09-07, NetQ 5.1 What's New re-fetched 2026-09-07. Dates are when each page was fetched.

  1. What Just Happened (WJH) | Cumulus Linux 5.18 · fetched 2026-09-07
  2. Configure and Monitor What Just Happened | Cumulus NetQ 5.1 · fetched 2026-09-07
  3. gNMI Streaming | Cumulus NetQ 5.1 · fetched 2026-09-07
  4. What's New | Cumulus Linux 5.18 · fetched 2026-09-07
  5. What's New | Cumulus NetQ 5.1 · fetched 2026-09-07
  6. New and Removed NVUE Commands | Cumulus Linux 5.18 · fetched 2026-09-07
  7. Network Troubleshooting | Cumulus Linux 5.18 · fetched 2026-09-07
  8. NVUE CLI | Cumulus Linux 5.18 · fetched 2026-09-07

The same idea elsewhere

Other lessons that cover this ground, sometimes from another course's angle.