Discover exporters from NetBox
netbox-api reads /api/dcim/devices/ directly, follows pagination to completion, and passes your filter in NetBox's own query terms.
If the netbox-plugin-prometheus-sd plugin is already installed and you would rather not touch it, follow Discover exporters from Prometheus service discovery instead.
Prerequisites
| Requirement | Detail |
|---|---|
| A NetBox API token | Read access to devices. Stored where a secret reference can resolve it. |
| Every device has a primary IPv4 or IPv6 | A device with neither is skipped and counted on discovery.skipped. |
| Device names unique across the devices the filter returns | Two devices with one name and different addresses refuse the whole poll. NetBox enforces uniqueness per site only. |
| An internal CA, if NetBox uses one | In riptide.http.ca-bundle, see Outbound TLS. |
No exporters tree in the inventory file | Discovery owns that tree; a file that declares one fails startup and every later poll. |
Steps
-
Store the token where riptide can resolve it, for example in Vault at
secret/netboxunder the keytoken. -
Write the discovery block into
/etc/riptide/config.yaml. Develop the filter against NetBox directly and paste in what works; it is passed through unchanged.riptide:discovery:type: netbox-apiurl: https://netbox.example.com/api/dcim/devices/token: vault://secret/netbox#tokenfilter: status=active&role=leaf&role=spineinterval: 60sinventory:file: /etc/riptide/inventory.yamlLeave
address-labelsunset:netbox-apiemits exactly the default two names, and a customised list fails startup. -
Reduce
/etc/riptide/inventory.yamlto agent ranges only.riptide:snmp:agents:"10.20.0.0/16":credentials: corp-v3polling: default -
Restart the collector and read the inventory line.
journalctl -u riptide -n 200 | grep -E 'Inventory|Boot could not reach'Expected output:
2026-09-23T14:40:41.098+02:00 INFO 23358 --- [ main] org.riptide.inventory.Inventory : Inventory loaded from /etc/riptide/inventory.yaml + https://netbox.example.com/api/dcim/devices/: 1 agent ranges, 2 enrichment entries2026-09-23T14:40:41.140+02:00 INFO 23358 --- [ main] o.riptide.config.InventoryFileReloader : Inventory hot-reload enabled: watching /etc/riptide/inventory.yaml + https://netbox.example.com/api/dcim/devices/ every PT1MA
WARN Boot could not reach ...line instead means NetBox was down at boot; the collector runs without exporter names until the next successful poll. -
Verify the gauges on the management port.
curl -s http://localhost:8080/metrics | grep -E '^(discovery_|inventory_reload_)'Expected output:
discovery_skipped 1.0discovery_targets 2.0inventory_reload_dead 0.0inventory_reload_stale 0.0inventory_reload_failures 0.0inventory_reload_successes 0.0discovery_targetsis the number of exporter entries serving.discovery_skippedcounts devices the filter returned without a usable primary IP; here one of three devices had none.inventory_reload_successesstays at0.0until the first poll after boot finds a change.
Discover devices and virtual machines
NetBox serves devices and virtual machines from two endpoints.
List both under riptide.discovery.urls instead of url.
The token needs view permission on both object types.
A token that cannot view virtual machines gets an empty list, not an error, and riptide refuses the poll naming the virtual machine endpoint.
-
Replace
urlwithurlsin/etc/riptide/config.yaml. Every other key applies to both endpoints, the filter included. Use filter terms that both object types accept, such astag,statusorsite, and check the filter against each endpoint in NetBox directly. A device-only term such asmanufacturermeans nothing to the virtual machine endpoint.riptide:discovery:type: netbox-apiurls:- https://netbox.example.com/api/dcim/devices/- https://netbox.example.com/api/virtualization/virtual-machines/token: vault://secret/netbox#tokenfilter: tag=flow-exporterinterval: 60sinventory:file: /etc/riptide/inventory.yamlSetting both
urlandurlsfails startup naming both keys. -
Restart the collector and read the inventory line.
journalctl -u riptide -n 200 | grep -E 'Inventory loaded|Boot could not reach'Expected output:
2026-09-25T02:20:20.109+02:00 INFO 56752 --- [ main] org.riptide.inventory.Inventory : Inventory loaded from /etc/riptide/inventory.yaml + https://netbox.example.com/api/dcim/devices/, https://netbox.example.com/api/virtualization/virtual-machines/: 2 agent ranges, 7 enrichment entriesThe enrichment entries are the tagged devices plus the tagged virtual machines with a primary IP. A virtual machine with no primary IP is counted on
discovery_skipped.
Riptide reads the endpoints in order on every poll and publishes only when both answer. One endpoint that is down, answers 404 or answers empty keeps the last good inventory serving for both, and the log names that endpoint. A device and a virtual machine with the same name and different addresses are refused as a collision, each address followed by its endpoint.
Related
- Discovery reference: every key, the limits, and every message.
- How discovery composes the inventory: what is refused and why, and what a boot with NetBox down does.
- Discover exporters from Nautobot:
netbox-apicannot read Nautobot.
Open questions
- The output above was captured on 2026-09-23 against a local stand-in serving a three-device NetBox page, not against a NetBox server; the inventory path and the URL in the quoted lines were substituted for the stand-in's. An earlier session verified this source against a real NetBox; this page's output was not captured there.
journalctlwas not run; the lines were read from the collector's stdout.- The devices-and-virtual-machines output was captured on 2026-09-25 against a real NetBox
v4.7-5.1.1lab onhttp://localhost:18000, with 7 tagged devices and 3 tagged virtual machines, one without a primary IP. The URL and the inventory path in the quoted line were substituted.