'\" t
.\" Title: nvme-fabrics.conf
.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 10/30/2026
.\" Manual: NVMe Manual
.\" Source: NVMe
.\" Language: English
.\"
.TH "NVME\-FABRICS\&.CONF" "5" "10/30/2026" "NVMe" "NVMe Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
nvme-fabrics.conf \- NVMe\-oF connection configuration file format
.SH "SYNOPSIS"
.sp
.nf
\fI/usr/local/etc/nvme/nvme\-fabrics\&.conf\fR
\fI/usr/local/etc/nvme/nvme\-fabrics\&.conf\&.d/*\&.conf\fR
.fi
.SH "DESCRIPTION"
.sp
An INI\-format file describing which NVMe over Fabrics (NVMe\-oF) controllers a host should connect to, and with what parameters\&. This file is read by \fInvme connect\-all\fR, \fInvme discover\fR and \fInvme connect\fR, and by the nvme\-discoverd daemon\&.
.sp
Other orchestrators read the same format through the same parser, but from a file of their own: nvme\-stas reads its configuration through the Python bindings\&. The file name is a parameter of every entry point, so each orchestrator names its own and is unaffected by the others\*(Aq\&.
.sp
A configuration is a main file plus an optional drop\-in directory, the same \fIfoo\&.conf\fR + \fIfoo\&.conf\&.d/\fR pattern systemd uses\&. Both parts are read independently, and either may be absent; an absent configuration is not an error; it simply yields no connections\&.
.sp
\-\-config FILE (on \fIconnect\-all\fR/\fIdiscover\fR/\fIconnect\fR) names the main file; its drop\-in directory is always \fIFILE\&.d/\fR\&. Omitting \-\-config uses the default path above\&.
.SH "SECTIONS"
.sp
Each section is one or more \fIkey = value\fR lines\&. An empty value (\fIkey =\fR) resets the key to the kernel default, overriding whatever an outer scope set (see RESETTING A KEY below)\&. Unknown keys are ignored\&. Boolean values accept \fI1\fR/\fIyes\fR/\fIy\fR/\fItrue\fR/\fIt\fR/\fIon\fR and \fI0\fR/\fIno\fR/\fIn\fR/\fIfalse\fR/\fIf\fR/\fIoff\fR (case\-insensitive)\&.
.PP
\fI[Host]\fR
.RS 4
Optional, at most one per file\&. The identity used by every connection in that file:
\fIhostnqn\fR,
\fIhostid\fR,
\fIhostsymname\fR, plus any SECURITY key below\&. A file with no
\fI[Host]\fR
connects as the system default identity (\fI/usr/local/etc/nvme/hostnqn\fR
/
\fIhostid\fR)\&. A drop\-in that defines
\fI[Host]\fR
must set
\fIhostnqn\fR
explicitly\&.
.RE
.PP
\fI[Discovery Controller Defaults]\fR, \fI[I/O Controller Defaults]\fR
.RS 4
Optional, at most one of each per file\&. Default TUNABLE values for connections of that class, drawn from below\&. A drop\-in\(cqs copy overlays the top\-level file\(cqs, for that drop\-in\(cqs own connections only\&.
.RE
.PP
\fI[Discovery Controller]\fR
.RS 4
One Discovery Controller to connect to\&. Repeatable\&.
\fInqn =\fR
defaults to the well\-known discovery NQN if omitted\&.
.RE
.PP
\fI[Subsystem]\fR
.RS 4
One I/O subsystem to connect to, named by
\fInqn =\fR\&. Repeatable\&.
.RE
.sp
Both endpoint sections accept any TUNABLE or SECURITY key as a per\-section override, plus one or more \fIcontroller =\fR lines (below)\&. A section with no \fIcontroller =\fR line makes no connection\&. It can still give the KX\-HMAC\-CHAP secrets of a discovered controller (see DISCOVERED CONTROLLERS below)\&.
.SH "CONTROLLER LINES"
.sp
Each \fIcontroller =\fR line under a \fI[Discovery Controller]\fR or \fI[Subsystem]\fR section is one path to that endpoint; repeating the key expresses multipath (native NVMe multipath groups all paths sharing a subsysnqn)\&. The value is a \fI;\fR\-separated \fIkey=value\fR list:
.sp
.if n \{\
.RS 4
.\}
.nf
controller = transport=tcp;traddr=10\&.0\&.0\&.9;trsvcid=4420;host\-iface=eth0
.fi
.if n \{\
.RE
.\}
.sp
\fItransport\fR and \fItraddr\fR are required; \fItrsvcid\fR, \fIhost\-traddr\fR and \fIhost\-iface\fR are optional\&. Any TUNABLE key may also appear on the line as a per\-path override \(em SECURITY keys may not, since they are bound to the (host, subsystem) pair, not to a single path\&.
.SH "KEYS"
.sp
TUNABLE (type default, \fI[Host]\fR, endpoint section, or \fIcontroller =\fR line):
.sp
.if n \{\
.RS 4
.\}
.nf
nr\-io\-queues, nr\-write\-queues, nr\-poll\-queues, queue\-size,
keep\-alive\-tmo, reconnect\-delay, ctrl\-loss\-tmo, fast\-io\-fail\-tmo,
tos, duplicate\-connect, disable\-sqflow, hdr\-digest, data\-digest
.fi
.if n \{\
.RE
.\}
.sp
SECURITY (\fI[Host]\fR or endpoint section only, never a \fIcontroller =\fR line):
.sp
.if n \{\
.RS 4
.\}
.nf
tls, tls\-key, tls\-key\-identity, keyring, concat, kxchap\-secret,
kxchap\-ctrl\-secret, tls\-key\-source
.fi
.if n \{\
.RE
.\}
.sp
IDENTITY (\fI[Host]\fR only):
.sp
.if n \{\
.RS 4
.\}
.nf
hostnqn, hostid, hostsymname
.fi
.if n \{\
.RE
.\}
.sp
Every key here except \fItls\-key\-source\fR is the same name as its \fInvme connect\fR long option (hyphenated)\&. See \fBnvme-connect\fR(1) for what each one means\&.
.sp
\fItls\-key\-source\fR says where the TLS PSK comes from:
.PP
\fIinline\fR
.RS 4
The default\&.
\fItls\-key\fR
is the key itself\&.
.RE
.PP
\fIsystemd\-creds\fR
.RS 4
\fItls\-key\fR
is the name of a systemd credential\&. nvme\-keysd reads the credential and puts the PSK in the keyring\&. The connection does not use
\fItls\-key\fR: the kernel finds the PSK in the keyring by the host NQN and the subsystem NQN\&. See
\fBnvme-keysd\fR(8)\&.
.RE
.PP
\fIkmip:\fR
.RS 4
\fItls\-key\fR
is the Name of a key on the key management server (KMS)
\fI\fR, configured in nvme\-keysd\&.conf\&. nvme\-keysd gets the key and puts it in the keyring\&.
\fIkmip\fR
alone is enough when only one KMS is configured\&. See
\fBnvme-keysd\fR(8)\&.
.RE
.sp
Any other value also means that \fItls\-key\fR is not the key\&. libnvme does not check the value: nvme\-keysd does\&.
.SH "RESETTING A KEY"
.sp
An empty assignment (\fIkey =\fR) resets that key to the kernel default, undoing whatever an outer scope (a \fI*Defaults\fR section or \fI[Host]\fR) set\&. This differs from simply not writing the key, which instead inherits through the cascade below\&.
.SH "PRECEDENCE"
.sp
A key resolves most\-specific first:
.sp
.if n \{\
.RS 4
.\}
.nf
controller = line > endpoint section > [Host] > type defaults > kernel default
.fi
.if n \{\
.RE
.\}
.sp
The type\-defaults level is chosen by the connection\(cqs class: a Discovery Controller draws from \fI[Discovery Controller Defaults]\fR, an I/O Controller from \fI[I/O Controller Defaults]\fR\&.
.SH "DISCOVERED CONTROLLERS"
.sp
A controller found through discovery (an I/O controller or a referral in a discovery log page, or a Discovery Controller found through mDNS) has no section of its own\&. It gets \fIkxchap\-secret\fR and \fIkxchap\-ctrl\-secret\fR from the endpoint section with the same \fInqn =\fR: a \fI[Subsystem]\fR section for an I/O controller, a \fI[Discovery Controller]\fR section for a Discovery Controller\&. The section must be in the same file as the Discovery Controller that reported the controller (the top\-level file for mDNS), because a secret belongs to one (host, subsystem) pair\&. The section\(cqs \fIcontroller =\fR lines do not matter: the addresses come from discovery\&.
.sp
A secret that no such section sets comes from the Discovery Controller: its \fIkxchap\-secret\fR for \fInvme connect\-all\fR, the defaults of its file for nvme\-discoverd\&. The \fIkxchap\-ctrl\-secret\fR of the Discovery Controller is never used\&. A \fI[Discovery Controller]\fR section with the well\-known discovery NQN never matches\&.
.sp
A Discovery Controller with the well\-known discovery NQN allows only unidirectional authentication\&. A \fI[Discovery Controller]\fR section with that NQN, or with no \fInqn =\fR, may set \fIkxchap\-secret\fR\&. If it sets \fIkxchap\-ctrl\-secret\fR, a warning is logged\&.
.sp
Two sections of the same type with the same NQN in one file share their secrets\&. If they set different values for the same secret, the file is rejected\&.
.sp
.if n \{\
.RS 4
.\}
.nf
[Subsystem]
nqn = nqn\&.2026\-10\&.com\&.example:sub1
kxchap\-secret = DHHC\-1:00:\&.\&.\&.
kxchap\-ctrl\-secret = DHHC\-1:00:\&.\&.\&.
.fi
.if n \{\
.RE
.\}
.SH "EXAMPLE"
.sp
.if n \{\
.RS 4
.\}
.nf
# /usr/local/etc/nvme/nvme\-fabrics\&.conf
[Discovery Controller Defaults]
keep\-alive\-tmo = 30
[I/O Controller Defaults]
keep\-alive\-tmo = 5
[Host]
hostsymname = lab\-host\-01
[Discovery Controller]
controller = transport=tcp;traddr=192\&.168\&.1\&.10;trsvcid=8009
[Subsystem]
nqn = nqn\&.2024\-01\&.com\&.example:data\&.vol1
controller = transport=tcp;traddr=192\&.168\&.1\&.20;trsvcid=4420
controller = transport=tcp;traddr=192\&.168\&.1\&.21;trsvcid=4420
.fi
.if n \{\
.RE
.\}
.sp
See \fI/usr/local/etc/nvme/nvme\-fabrics\&.conf\&.sample\fR for a longer, commented example\&.
.SH "SEE ALSO"
.sp
nvme\-connect\-all(1) nvme\-discover(1) nvme\-connect(1) nvme\-config\-convert(1) \m[blue]\fBhttps://github\&.com/linux\-nvme/nvme\-cli/blob/master/libnvme/design/CONFIG\&.md\fR\m[]
.SH "NVME"
.sp
Part of the nvme\-user suite