Validation Engines
NetBox Validation uses three engines that evaluate different aspects of infrastructure compliance. All three produce the same output and feed into the same findings, compliance scoring, and dashboard.
Intent Engine
The intent engine evaluates NetBox data to verify compliance with organizational policies. No device connectivity or external services required. 42 built-in checks cover addressing, redundancy, topology, standards, completeness, and security intent.
How It Works
Each intent check receives a device object and parameters, queries related NetBox data (interfaces, IPs, cables, VRFs, etc.), and returns pass/fail results. Checks run against the NetBox data model, which means they automatically respect branch context -- when validating a branch, NetBox returns the branch-overlay data.
Built-in Checks by Category
| Category | Checks | Examples |
|---|---|---|
| Addressing | 8 | no_duplicate_ips, loopback_has_host_route, ip_vrf_consistency |
| Redundancy | 7 | min_cabled_uplinks, min_bgp_sessions, redundant_power |
| Topology | 8 | leaf_spine_connectivity, symmetric_cabling, mtu_consistency_across_link |
| Standards | 6 | bgp_asn_range_consistent, interface_naming_consistent, vlan_id_range_by_site |
| Completeness | 8 | config_context_required_keys, asset_documentation_complete, ntp_syslog_configured |
| Security Intent | 5 | no_plaintext_secrets_in_context, management_vrf_enforced, restricted_prefix_usage |
See Check Reference for the complete list with parameters.
Parameters and Config Context
Most checks accept parameters to customize thresholds. Parameters merge with the check's defaults -- you only need to specify what you want to override:
{
"check_name": "min_cabled_uplinks",
"parameters": {"min_uplinks": 4}
}
Several checks derive expected values from NetBox's Config Context feature. This lets you define per-site, per-role, or per-device expectations without hardcoding them in rule parameters:
{
"ntp_servers": ["10.1.1.1", "10.1.1.2"],
"dns_servers": ["10.1.1.3"],
"bgp": {
"asn": 65001,
"neighbors": [
{"ip": "10.0.0.1", "asn": 65000}
]
}
}
Checks that use config context: min_bgp_sessions, config_context_required_keys, bgp_asn_range_consistent, no_forbidden_values_in_context, required_context_structure, no_plaintext_secrets_in_context.
Declarative Checks (No Code)
Declarative checks define validation rules entirely via rule parameters using a query + assert pattern. No code required. Set check_name to _declarative and put the logic in parameters:
{
"check_name": "_declarative",
"parameters": {
"query": {
"model": "dcim.interface",
"scope": "device",
"filters": {"enabled": true}
},
"assert": {
"method": "count",
"operator": "gte",
"value": 3
},
"fail_message": "Device has fewer than 3 active interfaces"
}
}
Query fields:
| Field | Description |
|---|---|
model | NetBox model in app.model format (e.g., dcim.interface, ipam.prefix) |
scope | device (objects related to current device), site (same site), or global |
filters | Filter kwargs applied to the queryset |
Supported models: dcim.interface, dcim.cable, dcim.device, dcim.powerport, dcim.consoleport, dcim.rearport, dcim.frontport, dcim.inventoryitem, dcim.devicebay, dcim.site, dcim.rack, ipam.ipaddress, ipam.prefix, ipam.vlan, ipam.vrf, circuits.circuit, circuits.circuittermination, circuits.provider, tenancy.tenant, tenancy.contact
Assertion methods:
| Method | Operates On | Example |
|---|---|---|
count | QuerySet count | {"method": "count", "operator": "gte", "value": 2} |
exists | Boolean existence | {"method": "exists", "operator": "eq", "value": true} |
field_value | Field on each object | {"method": "field_value", "field": "status", "operator": "eq", "value": "active"} |
field_unique | No duplicate values | {"method": "field_unique", "field": "name"} |
aggregate_sum | Sum of a numeric field | {"method": "aggregate_sum", "field": "speed", "operator": "gte", "value": 20000} |
aggregate_max | Max of a numeric field | {"method": "aggregate_max", "field": "mtu", "operator": "lte", "value": 9216} |
related_exists | Related object exists | {"method": "related_exists", "field": "primary_ip4"} |
Operators: eq, neq, gt, gte, lt, lte, in_list, not_in_list, regex, contains
Example -- every active device at site has a rack assignment:
{
"check_name": "_declarative",
"parameters": {
"query": {"model": "dcim.device", "scope": "site", "filters": {"status": "active"}},
"assert": {"method": "field_value", "field": "rack_id", "operator": "neq", "value": null},
"fail_message": "Active devices must be racked"
}
}
Limitations: Declarative checks cannot do multi-hop graph traversal, complex conditional logic, aggregation across multiple models, or branch-vs-main comparison. Use built-in checks for these.
Config Engine
Available to Premium tier customers. Enabled by default for Premium deployments.
The config engine performs offline structural analysis of rendered device configurations. It is currently powered by Batfish, an open-source network configuration analysis tool. Intent checks verify that NetBox data is compliant; config analysis verifies that the configs generated from that data are structurally sound.
The config engine requires that you use NetBox Config Templates to render device configurations. It analyzes configs rendered from these templates -- it cannot currently analyze configs from other sources. See the NetBox Config Templates documentation for details on setting up templates.
The config engine's network operating system (NOS) support is aligned with Batfish's. Batfish supports a wide range of platforms including Arista EOS, Cisco IOS/IOS-XR/NX-OS, Juniper JunOS, Palo Alto PAN-OS, and others. See the Batfish documentation for the full list of supported platforms.
How It Works
- NetBox Validation renders configs from each device's Config Template (Provisioning > Config Templates in NetBox)
- Configs are sent to the config analysis engine for parsing and structural analysis
- The engine builds a network model and runs structural checks
- Results flow into the same findings/compliance pipeline as intent checks
Enabling Config Analysis
The config engine is enabled by default for Premium tier customers. To use it:
- Set
enable_config_engine: trueon each policy that should run config checks - Add rules with
engine: "config" - Assign Config Templates to devices (via device, Platform, or DeviceRole) in NetBox
Config Templates
Config Templates use Jinja2 to render device configurations from NetBox data:
hostname {{ device.name }}
!
{% set cc = device.get_config_context() %}
{% if cc.ntp_servers is defined %}{% for ntp in cc.ntp_servers %}ntp server {{ ntp }}
{% endfor %}{% endif %}
!
{% for iface in device.interfaces.all() %}{% set ips = iface.ip_addresses.all() %}{% if ips %}
interface {{ iface.name }}
ip address `{{ ips | first }}`
!
{% endif %}{% endfor %}
Templates have access to the full device object: device.name, device.interfaces.all(), device.get_config_context(), device.platform.name, device.role.name, etc.
Test rendering via API: POST /api/dcim/devices/{id}/render-config/
See the NetBox Config Templates documentation for complete setup instructions.
Differential Analysis (Branches)
When validating a branch, the config engine renders configs from both main and the branch, then performs differential analysis:
- Lost reachability -- paths that existed before no longer work
- Broken BGP sessions -- previously compatible sessions become incompatible
- Routing regressions -- routes that existed before are no longer reachable
Two checks are branch-specific: differential_reachability and routing_changes. These only produce meaningful results when run against a branch.
35 Built-in Config Checks
| Category | Checks | Focus |
|---|---|---|
| Parse Quality | 4 | Config parse status, warnings, undefined references, unused structures |
| Routing Protocols | 11 | BGP sessions, OSPF compatibility, routing loops, multipath consistency, BGP attributes |
| IP & Topology | 5 | Duplicate IPs, IP ownership conflicts, L3 topology, MTU, HSRP/VRRP |
| ACL & Security | 7 | ACL reachability, traffic blocking assertions, prefix filters, auth config |
| Overlay | 3 | VXLAN VNI, EVPN L3 VNI consistency, SNMP communities |
| Reachability | 3 | Source-dest reachability, traceroute, route table completeness |
| Differential | 2 | Lost/new reachability, route changes between main and branch |
See Check Reference for the complete list.
If Config Analysis Is Not Available
Config rules produce skip results with a message explaining that the config engine is not available. Intent and graph checks work independently -- there is no config engine dependency for core validation.
Graph Engine
Available to Premium tier customers. Enabled by default for Premium deployments.
The graph engine builds an in-memory infrastructure dependency graph from NetBox's data models and runs resilience checks that evaluate cross-device physical dependencies. It answers questions like "what happens if this power feed fails?" and "which devices share a single point of failure?"
Enabling the Graph Engine
The graph engine is enabled by default for Premium tier customers. To use it, set enable_graph_engine: true on each policy that should run graph checks.
Three of the 16 graph checks also require the config analysis engine for routing-layer analysis (routing_convergence_impact, bgp_session_criticality, forwarding_path_redundancy). These operate independently of per-policy enable_config_engine -- they just need the config engine available at the deployment level.
What the Graph Engine Builds
- Power chains -- traces from device power ports through PDUs to power feeds and panels
- Network adjacency -- maps cabled interface connections between devices
- Circuit paths -- resolves circuit terminations to devices
- Physical hierarchy -- maps devices to racks and sites
- Failure domains -- identifies shared dependencies (feeds, panels, racks, upstream devices, circuit providers)
The engine widens scope automatically -- it collects all active devices at the scoped sites, not just the policy-targeted devices, to trace complete dependency chains.
16 Graph Checks
Power checks (6)
| Category | Checks | Focus |
|---|---|---|
| Power | 6 | Path completeness, redundancy, feed capacity, three-phase balance, feed/panel blast radius |
Topology and infrastructure checks (7)
| Category | Checks | Focus |
|---|---|---|
| Topology | 2 | Device and cable single points of failure |
| Infrastructure | 5 | Site connectivity, circuit diversity, rack failure impact, shared failure domains, concurrent maintainability |
Config-engine-enhanced checks (3)
| Category | Checks | Focus |
|---|---|---|
| Reachability | 3 | Routing convergence impact, BGP session criticality, forwarding path redundancy |
See Check Reference for complete parameters.
Understanding Graph Results
Graph checks produce two types of results:
- Per-device results (e.g.,
power_path_complete): one result per device, similar to intent checks - Per-failure-point results (e.g., blast radius, SPOF): one result per feed/panel/rack/cable, with the failure point name in the
devicefield and structured metadata inextra
Blast Radius and Severity Escalation
Blast radius findings group results by failure point and automatically escalate severity based on impact:
| Unprotected Devices | Escalation |
|---|---|
| 1--2 | No change |
| 3--5 | medium -> high |
| 6--10 | high -> critical |
| 10+ | Always critical |
The finding detail page shows a blast radius card with protected and unprotected device tables.
Combining Engines
Graph checks coexist with intent and config checks in the same policy:
name: Full Resilience Audit
enable_config_engine: true
enable_graph_engine: true
rules:
- name: No Duplicate IPs
engine: intent
check_name: no_duplicate_ips
severity: critical
- name: BGP Sessions
engine: config
check_name: bgp_sessions
severity: high
- name: Power Path Complete
engine: graph
check_name: power_path_complete
severity: high
Data Quality Requirements
Graph analysis is only as good as the data in NetBox:
- Power chain tracing requires: power ports on devices, cables from power ports to power feeds (or through PDU outlets), power feeds connected to power panels
- Network topology requires: cabled interfaces between devices
- Circuit analysis requires: circuit terminations linked to interfaces or sites
- Blast radius accuracy depends on all power paths being documented
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| All devices show "No power ports -- skipped" | Devices lack PowerPort components | Add PowerPort components to device types, or set skip_if_no_power_ports: false |
| Blast radius shows 0 affected devices | Power feeds aren't cabled to device power ports | Cable power ports to power feeds |
| "No circuits in scope" | Circuit terminations don't point to interfaces | Use interface-based terminations |
| Shared failure domain is slow | Too many devices (quadratic comparison) | Set max_devices parameter or use compare_roles to narrow scope |