NetBox Custom Fields: Extending Your Source of Truth Without a Fork
NetBox Custom Fields let you attach typed, API-accessible metadata to devices, IPs, and circuits without forking the code. Here's how to use them well — and where they bite.
18 Jun 2026, 14:47 UTC

Every network team eventually hits the same wall with NetBox: the built-in data model is excellent, but it doesn't know that your devices have a "maintenance window," that your circuits carry a "billing code," or that your IP addresses belong to a specific "application tier." You could stuff this into the description field (please don't), maintain a parallel spreadsheet (worse), or fork the codebase (worst). Custom Fields exist precisely for this gap, and used well they turn NetBox into a genuinely organization-specific source of truth.
The takeaway up front: Custom Fields let you attach typed, validated, API-accessible metadata to almost any NetBox object — but they work best when you treat them like a schema, not a junk drawer.
What Custom Fields actually are
A Custom Field is a named attribute you define for a specific NetBox model — Device, IPAddress, Circuit, Site, and so on. Once defined, it appears automatically in the web UI (both list and detail views), is filterable in searches, and shows up in the REST API payload for every object of that type. No code changes, no plugin, no restart gymnastics.
Fields are typed, which is the part people underestimate. Available types include:
- Text — free-form strings, optionally validated with a regex
- Integer — numbers with optional min/max bounds
- Boolean — true/false toggles
- Date — calendar values
- Choice — a value picked from a predefined list you maintain
Typing matters because NetBox enforces it. An integer field rejects "probably 4," and a choice field prevents the classic spreadsheet problem where "prod," "Prod," and "production" are three different environments.
A worked example: tracking device environment
Say you want every device tagged with its deployment environment so your Ansible inventory can group hosts correctly. Here's the flow:
1. Create the field. In the NetBox UI, navigate to Settings → Custom Fields (older versions: Customization → Custom Fields — the menu moved around the 3.x series, so check your version). Create a field named environment, assign it to the DCIM → Device model, and choose type Choice with options prod, staging, dev. Marking it required is tempting; resist until you've backfilled existing devices, or edits to old objects will fail validation.
2. Set values. Edit a device in the UI and pick an environment, or do it in bulk via the API. From any machine with network access to NetBox, using a token with write permission on devices:
curl -X PATCH \
-H "Authorization: Token <your-api-token>" \
-H "Content-Type: application/json" \
https://netbox.example.com/api/dcim/devices/123/ \
-d '{"custom_fields": {"environment": "prod"}}'Replace <your-api-token> and the device ID. A successful response returns the updated device object.
3. Verify. Fetch the device and confirm the field is present:
curl -H "Authorization: Token <your-api-token>" \
https://netbox.example.com/api/dcim/devices/123/ | jq '.custom_fields'You should see "environment": "prod" in the output. You can also filter devices by it: GET /api/dcim/devices/?cf_environment=prod — the cf_ prefix is how custom fields appear in API filters.
4. Consume it. Ansible's NetBox inventory plugin can group hosts on custom_fields.environment, so your playbooks automatically target the right tier. Terraform and plain scripts read the same JSON.
Where people go wrong
The failure mode isn't technical — it's governance. A few patterns worth adopting early:
- Cap the count. Every field is a column-like cost in the database and a cognitive cost in the UI. If a device detail page needs scrolling past twenty custom fields, you've built the spreadsheet you were trying to escape. Keep it to fields something actually consumes.
- Name like a schema. Use lowercase snake_case (
maintenance_window, notMaint Window!!) and document each field's meaning in NetBox's own description attribute. Future you, writing an API filter at 2 a.m., will be grateful. - Plan choice-list changes. Editing a choice list doesn't migrate existing values. Renaming
prodtoproductionleaves old devices pointing at a now-invalid option. Treat choice renames as a small migration: add the new option, bulk-update via API, then remove the old one.
The trade-offs
Custom Fields are not free. They add database rows and can slow queries on very large object collections, particularly if you filter heavily on them — keep an eye on query performance if you're filtering tens of thousands of devices by custom field values. They also lack the relational integrity of real NetBox models: if "environment" deserves its own attributes (contacts, change windows, SLA), it probably wants to be a proper object with a foreign key, not a text field. A good rule of thumb: if you're storing a pointer to something with its own lifecycle, model it properly instead.
There's also no cross-field validation — NetBox won't stop you from setting environment=prod on a device in a lab site. That logic belongs in your automation or a validation plugin.
Start small, verify, then scale
Pick one piece of metadata your team currently tracks outside NetBox — environment, owner, maintenance window — and model it as a single Custom Field this week. Set a few values, confirm them via the API with the cf_ filter, and wire one consumer (an inventory group, a report) to it. Once that loop works, you'll have a repeatable pattern for everything else — and one less spreadsheet to reconcile.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.