---
name: "nvme-discoverd"
section: "8"
platform: "linux"
package: "nvme-cli"
version: "3.2-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/nvme-discoverd"
---

# nvme-discoverd(8)

NVMe-oF discovery and connectivity daemon

## NAME

nvme-discoverd - NVMe-oF discovery and connectivity daemon

## SYNOPSIS

```
nvme-discoverd [--config=<FILE>] [--nvme-path=<PATH>] [--debug] [--help]
```

## DESCRIPTION

nvme-discoverd is a persistent daemon that connects the host’s desired NVMe-oF controllers and keeps them connected. It reads three sources to build its set of desired connections: the NBFT ACPI table (boot-time controllers), the shared NVMe-oF fabrics configuration ([nvme-fabrics.conf(5)](/nvme-fabrics.conf/5.md)), and the Discovery Log Pages of any Discovery Controllers it connects to (including FC targets found via FC kickstart). It never disconnects a live controller in response to a discovery change; the only disconnects it causes are a side effect of stopping its own systemd units, at shutdown or on request.

At shutdown, a unit is stopped only after the file systems mounted with the *\_netdev* option are unmounted. A file system on an NVMe-oF namespace must use *\_netdev* in [fstab(5)](/fstab/5.md). Without it, the controller can be disconnected while the file system is still mounted.

Every connection attempt is delegated to *nvme connect*, which runs inside a systemd transient unit instead of writing directly to /dev/nvme-fabrics. As a result, a stuck connect attempt never blocks the daemon’s event loop. Each unit is named after a hash of the controller’s transport identity.

Failed connections retry with exponential backoff. Discovery Controllers from NBFT or the fabrics config represent explicit intent, so they always retry forever. A Discovery Controller found only through a referral or FC kickstart is different: it gives up after *dc-giveup-timeout* (default 72hours) of unbroken failure and is dropped from tracking.

A TLS connection needs [tlshd(8)](/tlshd/8.md) from ktls-utils. Enable it with *systemctl enable --now tlshd*. When both are enabled, nvme-discoverd starts after tlshd.

Before connecting or reconnecting anything, nvme-discoverd checks the system-wide exclusion list. It also registers ownership of every controller it connects (--owner discoverd, or --owner nbft for an NBFT-sourced controller) in the NVMe-oF ownership registry. See [nvme-registry-list(1)](/nvme-registry-list/1.md) and [nvme-exclusion-add(1)](/nvme-exclusion-add/1.md).

A Discovery Controller that has no owner, for example one connected with *nvme discover --persistent*, is not tracked. When its discovery log changes, or when it reconnects, nvme-discoverd runs *nvme connect-all* for it in a transient unit, as the legacy udev rules do. The connections it makes have no owner, and *nvme disconnect-all* removes them. Events from a Discovery Controller with another owner are ignored.

nvme-discoverd is still experimental. It is meant to replace the older udev-rule/systemd-unit autoconnect mechanism. By default, the legacy mechanism is built only when nvme-discoverd is not. Building with *-Dnvmf-autoconnect=enabled* installs both. The legacy udev rules are active as soon as they are installed. nvme-discoverd runs only when the administrator enables it with *systemctl enable --now nvme-discoverd*. While nvme-discoverd is active, nvmf-autoconnect.service and the FC kickstart skip their connect step.

## OPTIONS

- \-c \<FILE\>, --config=\<FILE\>

  Path to the daemon’s own configuration file. Default: /usr/local/etc/nvme/nvme-discoverd.conf; see CONFIGURATION below. A missing file is not an error — every knob keeps its default.

- \--nvme-path=\<PATH\>

  Absolute or relative path to the *nvme* binary that transient connection units exec. Default: /usr/local/sbin/nvme. Mainly useful for running nvme-discoverd against a locally built *nvme* instead of the installed one.

- \-d, --debug

  Enable debug-level logging for both nvme-discoverd and the libnvme calls it makes, overriding the configured debug-level.

- \-h, --help

  Print usage and exit.

## CONFIGURATION

nvme-discoverd.conf holds the daemon’s own knobs, in a *\[Global\]* section and a *\[Discovery\]* section:

```
[Global]
nbft = true
debug-level = info
```

```
[Discovery]
epcsd-poll-interval-minutes = 15
fc-kickstart-interval-minutes = 0
dc-giveup-timeout = 72hours
zeroconf = false
```

*nbft* (boolean, default true) adopts and connects controllers listed in the NBFT ACPI table. *debug-level* (err, warn, info, or debug; default info) sets the log threshold; *--debug* on the command line overrides it.

*epcsd-poll-interval-minutes* (default 15, minimum 1) sets how often, in minutes, to reconnect and re-check a DC whose effective EPCSD (Explicit Persistent Connection Support for Discovery) is 0. Such a DC is disconnected between checks. *fc-kickstart-interval-minutes* (default 0) re-issues FC kickstart every N minutes; 0 = only at startup and on every FC controller drop. *dc-giveup-timeout* (default 72hours) is the give-up horizon described above. It takes a systemd time span ("72hours", "3 days 5 hours") or a unit-less value in seconds; "infinity" = never give up, 0 = give up on the first failure.

A DC connects with a keep-alive timeout of 30 seconds, or with its configured *keep-alive-tmo* (see [nvme-fabrics.conf(5)](/nvme-fabrics.conf/5.md)). A DC configured with *persistent = no* connects with none.

*zeroconf* (boolean, default false) connects to and manages Discovery Controllers found through mDNS (TP8009). It requires systemd-resolved v258 or later with mDNS enabled (*MulticastDNS=yes*), and an nvme-discoverd built with mDNS support. It is re-read on SIGHUP.

The connections nvme-discoverd manages come entirely from the shared fabrics configuration, not from this file: which Discovery Controllers and subsystems to connect, host identity, per-connection parameters. See [nvme-fabrics.conf(5)](/nvme-fabrics.conf/5.md).

## SIGNALS

SIGHUP

Reload both nvme-discoverd.conf and the shared fabrics configuration. Newly desired connections are started; nothing already connected is ever disconnected by a reload. If the fabrics configuration fails to reload (e.g. a syntax error), the previous one is kept and the failure is logged.

SIGTERM, SIGINT

Shut down gracefully.

## FILES

/usr/local/etc/nvme/nvme-discoverd.conf

The daemon’s own configuration; see CONFIGURATION.

/usr/local/etc/nvme/nvme-discoverd.conf.sample

A commented example of nvme-discoverd.conf with every knob at its default. It is not read; copy it to nvme-discoverd.conf to change a setting.

/usr/local/etc/nvme/nvme-fabrics.conf, /usr/local/etc/nvme/nvme-fabrics.conf.d/\*.conf

The connections nvme-discoverd manages; see [nvme-fabrics.conf(5)](/nvme-fabrics.conf/5.md).

/run/nvme/discoverd/

Runtime state linking each connected controller to the systemd transient unit that owns it. Does not survive a reboot.

## SEE ALSO

[nvme-fabrics.conf(5)](/nvme-fabrics.conf/5.md) [tlshd(8)](/tlshd/8.md) [nvme-connect(1)](/nvme-connect/1.md) [nvme-registry-list(1)](/nvme-registry-list/1.md) [nvme-exclusion-add(1)](/nvme-exclusion-add/1.md)

## NVME

Part of the nvme-user suite
