> ## Documentation Index
> Fetch the complete documentation index at: https://wireblast.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> Symptom, cause, fix, for the errors you are actually likely to hit.

Wireblast tries to fail before it touches anything, and to say what would fix it. If you're here, something got past that. These are the ones people actually hit.

## It won't start

<AccordionGroup>
  <Accordion title="insufficient privileges">
    ```text theme={null}
    error  insufficient privileges
           AF_XDP needs to create raw sockets and load an XDP program, which
           requires root or CAP_NET_RAW.
    ```

    Run it with `sudo`, or grant the capabilities once:

    ```bash theme={null}
    sudo setcap cap_net_raw,cap_bpf,cap_sys_resource+ep $(command -v wireblast)
    ```

    Re-apply that whenever you replace the binary, since capabilities live on the file.

    **If `sudo wireblast` says "command not found"**, you installed with `go install` and the binary is in your user's `GOPATH`, which root's `PATH` doesn't include. Copy it to `/usr/local/bin`.
  </Accordion>

  <Accordion title="locked-memory limit too low">
    ```text theme={null}
    error  locked-memory limit too low
           this run needs about 118 MiB of locked memory (12 queues x 4096 frames
           x 2048 bytes), but the limit is 8 MiB.
    ```

    The most common first-run failure. Three fixes, all fine:

    ```bash theme={null}
    ulimit -l 121634          # this shell only
    ```

    ```bash theme={null}
    # /etc/security/limits.conf, permanent
    * soft memlock unlimited
    * hard memlock unlimited
    ```

    ```bash theme={null}
    sudo wireblast --queues 3 ...    # less memory, no host changes
    ```

    Wireblast already raises its own soft limit to the hard limit before checking, so if you're seeing this, the hard limit is the binding one.
  </Accordion>

  <Accordion title="no interface named ...">
    ```text theme={null}
    wireblast: no interface named "vlan.2131"
    ```

    Check the name with `ip -br link show`. If you meant a VLAN, see the next entry.
  </Accordion>

  <Accordion title="... is a VLAN sub-interface">
    ```text theme={null}
    vlan.2043 is a VLAN sub-interface (VLAN 2043 on eno2). AF_XDP attaches to the
    physical NIC, so use --interface eno2 --vlan 2043 instead and Wireblast will
    emit tagged frames itself.
    ```

    Do what it says. Details in [VLAN-tagged traffic](/guides/vlan).
  </Accordion>

  <Accordion title="XDP program is already attached">
    ```text theme={null}
    open AF_XDP on eno2: afxdp: could not open eno2 (12 queues): generic attach:
    afxdp: XDP program id 1234 is already attached
    ```

    Something else owns the interface. Either another Wireblast is running:

    ```bash theme={null}
    pgrep -a wireblast
    ```

    Or a previous run died without cleaning up, which is possible on kernels older than 5.9, where the program isn't tied to the process lifetime. Clear it:

    ```bash theme={null}
    sudo ip link set dev eno2 xdp off
    ```

    Confirm it's gone with `ip link show eno2`. There should be no `xdp` in the output.
  </Accordion>
</AccordionGroup>

## It won't accept my settings

<AccordionGroup>
  <Accordion title="packet-size is out of range ... with a VLAN tag">
    ```text theme={null}
    --packet-size 64 is out of range for --mode udp with a VLAN tag; use 68-9018
    ```

    A tagged frame can't be smaller than 68 bytes. Use 68. [Why](/guides/vlan#the-68-byte-minimum).
  </Accordion>

  <Accordion title="packets are larger than the interface MTU">
    ```text theme={null}
    error  packets are larger than the interface MTU
           eno2 has an MTU of 1500, but the largest packet carries 1980 bytes
           above the Ethernet header.
           Use --packet-size 1518 or smaller, or raise the MTU yourself with
           `sudo ip link set eno2 mtu 2000`.
    ```

    Wireblast will not change your MTU. Either send smaller frames or raise it yourself.

    The VLAN tag doesn't count against the MTU, which is why a 1500-byte MTU accepts `--packet-size 1522` when tagged.
  </Accordion>

  <Accordion title="raw Ethernet frames carry no IP addresses">
    ```text theme={null}
    raw Ethernet frames carry no IP addresses, so there is nothing to resolve a
    next-hop MAC from.
    Give an explicit --dst-mac (or fill in Destination MAC in the wizard) to continue.
    ```

    `--mode raw` always needs `--dst-mac`.
  </Accordion>

  <Accordion title="has no IPv4 address to send from">
    ```text theme={null}
    wireblast: eno2 has no IPv4 address to send from; set --src-ip explicitly
    ```

    Normal on a NIC used only for testing, especially when the addresses live on a VLAN sub-interface. Pass `--src-ip`. It doesn't have to be an address the host owns, because nothing needs to route back.
  </Accordion>

  <Accordion title="rx-mode all requires --allow-match-all">
    ```text theme={null}
    --rx-mode all redirects EVERY packet on eno2 away from the kernel, taking SSH, DNS
    and all other traffic on this interface with it. Pass --allow-match-all if
    that is really what you want
    ```

    Working as intended. `--yes` deliberately doesn't cover this. See [transmit and receive](/concepts/receive#the-match-all-guard).
  </Accordion>

  <Accordion title="the destination did not answer ARP">
    ```text theme={null}
    the destination 192.0.2.10 did not answer ARP on eno2, so its MAC address is
    unknown.
    ```

    Either it isn't reachable (`ping -c1` it), or you're deliberately sending at something that won't answer, in which case pass `--dst-mac` directly. Wireblast never falls back to broadcast. Full decision tree in [flows and addressing](/patterns/flows#working-out-the-next-hop-mac).
  </Accordion>
</AccordionGroup>

## It runs, but the numbers are wrong

<AccordionGroup>
  <Accordion title="It seems to hang for ten seconds at startup">
    It isn't hanging:

    ```text theme={null}
    attaching XDP to eno2 and waiting for the link...
    link came back after 11.8s
    ```

    Attaching native XDP reinitialises the driver's queues, which drops carrier. Normal, and the run clock doesn't start until it's back. Rerunning with `r` in the TUI skips it entirely. [More](/concepts/how-it-works#why-the-link-drops-on-the-first-run).
  </Accordion>

  <Accordion title="bwm-ng shows a lower number than Wireblast">
    Expected. The kernel's counters exclude the FCS, and on a VLAN sub-interface they also exclude the Ethernet header and tag. About 6% at 64-byte frames, 1% at IMIX.

    Point `bwm-ng` at the physical NIC and it lands just under Wireblast's L2. [Full explanation](/concepts/numbers#why-bwm-ng-disagrees-with-both).
  </Accordion>

  <Accordion title="Which bit rate should I use?">
    **L1** for link utilisation, the "am I filling the pipe" question. **L2** for the frame you asked for. `--bps` is measured in L1.
  </Accordion>

  <Accordion title="It says generic XDP, not native">
    Your driver has no native XDP support, so the kernel fell back. It still works, just much slower and it drops under load. See [hardware and drivers](/concepts/hardware).

    On AWS, ENA needs at least two combined queues and an MTU at or below 3000:

    ```bash theme={null}
    sudo ethtool -L ens5 combined 2
    sudo ip link set ens5 mtu 3000
    ```
  </Accordion>

  <Accordion title="The actual rate is below what I set">
    If TX errors are zero, you've found the box's limit rather than a fault. [Finding your max rate](/guides/max-rate) walks through isolating whether it's the CPU, the NIC or the path.
  </Accordion>

  <Accordion title="The receiver counts fewer packets than the sender sent">
    Check `Drops/errors` on the receiver. Climbing means its rings filled up, so try more queues or a lower rate. Clean but short means the loss is in the path between them, not at either end.
  </Accordion>
</AccordionGroup>

## Getting back to a clean state

```bash theme={null}
# Is anything still running?
pgrep -a wireblast

# Is an XDP program still attached?
ip link show eno2 | grep xdp

# Clear it
sudo ip link set dev eno2 xdp off

# Forget saved settings
sudo wireblast --forget
```

On kernel 5.9 and later the program is held by a BPF link the kernel tears down when the process dies, so a crashed Wireblast cleans up after itself. On older kernels, the manual `xdp off` is your recovery.
