src/go/plugin/go.d/discovery/sdext/discoverer/snmpsd/README.md
Kind: snmp
Netdata can automatically discover SNMP-capable devices on your network and generate snmp collector jobs for each one. Configure the IP ranges to scan and the SNMP credentials to try, and the discoverer probes each address, reads basic system information, and produces collector configurations from a set of customisable service rules.
This page covers SNMP-specific setup. For the broader Service Discovery model (discoverer: and services: blocks, rule evaluation order, and the full template helper reference shared by all discoverers), see Service Discovery.
Each discovery cycle, the discoverer:
networks[] subnets, in parallel.system MIB (sysDescr, sysName, sysContact, sysLocation, sysObjectID).device_cache_ttl has not expired..IPAddress, .SysInfo.*, and .Credential.* to the rule engine.services: rules against each target. The rules render Go templates to produce one (or more) snmp collector job configurations.The discoverer never queries device-specific OIDs — those are queried later by the snmp collector once the job is created.
/23 network or smaller). Split larger ranges into multiple networks[] entries.networks[] entry is bound to exactly one credential. There is no automatic credential fallback. To probe the same subnet with multiple credentials, list it twice with different credential values; each device that responds to either credential will appear as a target (with its responding credential exposed via .Credential.*).system MIB. Vendor-specific identification (.SysInfo.Vendor, .Category, .Model) is derived from sysObjectID and an enterprise-numbers table; values may be empty or Unknown for devices that are not in that table.parallel_scans_per_network is high and the device is rate-limited). Engine IDs are not cached across probes, so devices that rotate engine IDs (rare; some HA pairs do this on failover) are handled transparently./etc/netdata/go.d/sd/snmp.conf (file-based pipelines) and in the agent's dynamic-configuration store under /var/lib/netdata/dyncfg/ (UI-managed pipelines). To avoid plaintext credentials on disk in either path, reference them via ${env:VAR} or ${file:/path} (see Secrets Management).You can configure the snmp discoverer in two ways:
| Method | Best for | How to |
|---|---|---|
| UI | Fast setup without editing files | Go to Collectors -> go.d -> ServiceDiscovery -> snmp, then add a discovery pipeline. |
| File | File-based configuration or automation | Edit /etc/netdata/go.d/sd/snmp.conf and define the discoverer: and services: blocks. |
Decide which subnets to scan and which SNMP credentials apply to each. SNMPv1 and SNMPv2c need a community string. SNMPv3 needs a USM username, security level, and (depending on the level) authentication and privacy passphrases.
The Netdata Agent host must be able to reach UDP port 161 on every scanned IP. SNMP devices typically restrict which clients can query them — make sure the Netdata host is allowed by any device-side ACLs.
The configuration file has two top-level blocks: discoverer: (the options below) and services: (rules that turn discovered devices into snmp collector jobs — see Service Rules).
After editing the file, restart the Netdata Agent to load the updated discovery pipeline.
| Option | Description | Default | Required |
|---|---|---|---|
| rescan_interval | How often to rescan configured networks for devices. | 30m | no |
| timeout | Maximum time to wait for an SNMP device response. | 1s | no |
| device_cache_ttl | How long to trust cached discovery results before re-probing a device. | 12h | no |
| parallel_scans_per_network | How many IPs to probe concurrently within each subnet. | 32 | no |
| credentials | List of SNMP credentials referenced by entries in networks. At least one credential is required. | yes | |
| networks | List of subnets to scan, each tagged with the credential name to use. At least one network is required. | yes |
<a id="option-rescan-interval"></a>
Set to 0 to perform a single discovery scan when the agent starts and never rescan. Negative values also disable rescanning.
<a id="option-device-cache-ttl"></a>
Set to 0 to never expire cached results — once a device is discovered it is never re-probed (until the agent restarts and the cache is invalidated by configuration changes).
<a id="option-credentials"></a>
Each credential has a name (used by networks[].credential) and a version.
Accepted version values: 1, 2, 2c, 3. (2 is an alias for 2c.)
For SNMPv1 and SNMPv2c, set community.
For SNMPv3, set:
username — USM user name.security_level — one of noAuthNoPriv, authNoPriv, authPriv.auth_protocol — one of md5, sha (HMAC-SHA-1, RFC 3414), sha224, sha256, sha384, sha512 (HMAC-SHA-2, RFC 7860). Required for authNoPriv and authPriv.auth_password — authentication passphrase. Required when auth_protocol is set.priv_protocol — one of des, aes (AES-128), aes192, aes256, aes192c, aes256c. The c variants are the Cisco/Reeder draft; check your device's show snmp user output to pick the matching one. Required for authPriv.priv_password — privacy passphrase. Required when priv_protocol is set.context_name — only set this if your devices use a non-default SNMPv3 context.Naming note: the YAML keys are auth_password and priv_password. The same fields are exposed inside service rule templates as .Credential.AuthPassphrase and .Credential.PrivacyPassphrase (the Go struct names). Both refer to the same value.
Avoid plaintext on disk: any of these fields can be sourced from environment variables or files using ${env:VAR_NAME} or ${file:/absolute/path} — see Secrets Management.
<a id="option-networks"></a>
Each entry needs subnet (an IP range) and credential (the name of an entry from credentials).
Supported subnet formats (IPv4 and IPv6):
192.168.1.0/24, 2001:db8::/12010.0.0.1-10.0.0.50, 2001:db8::-2001:db8::ff192.168.1.0/255.255.255.0192.168.1.10, 2001:db8::1Maximum 512 IPs per subnet entry. Split larger blocks across multiple entries.
For CIDR notation, network and broadcast addresses are excluded (except /31, /32, /127, /128).
Collectors -> go.d -> ServiceDiscovery -> snmp.Define the discovery pipeline in /etc/netdata/go.d/sd/snmp.conf.
The file has two top-level blocks: discoverer: (the options above) and services: (rules that turn discovered targets into collector jobs — see Service Rules).
After editing the file, restart the Netdata Agent to load the updated discovery pipeline.
Scan a single /24 with the default public community.
disabled: no
discoverer:
snmp:
credentials:
- name: public-v2c
version: 2c
community: public
networks:
- subnet: 192.168.1.0/24
credential: public-v2c
services:
- id: snmp
match: '{{ true }}'
Mix SNMPv2c on one subnet with SNMPv3 (authPriv) on another. Credentials are referenced from environment variables to keep them out of plaintext on disk.
disabled: no
discoverer:
snmp:
rescan_interval: 1h
credentials:
- name: public-v2c
version: 2c
community: ${env:SNMP_V2C_COMMUNITY}
- name: secure-v3
version: 3
security_level: authPriv
username: netdata-monitor
auth_protocol: sha256
auth_password: ${env:SNMP_V3_AUTH}
priv_protocol: aes256
priv_password: ${env:SNMP_V3_PRIV}
networks:
- subnet: 192.168.10.0/24
credential: public-v2c
- subnet: 10.20.30.0/24
credential: secure-v3
services:
- id: snmp
match: '{{ true }}'
Scan a small IPv6 range with SNMPv2c.
disabled: no
discoverer:
snmp:
credentials:
- name: public-v2c
version: 2c
community: public
networks:
- subnet: 2001:db8:0:1::/120
credential: public-v2c
services:
- id: snmp
match: '{{ true }}'
A services: rule turns each discovered SNMP device into one or more snmp collector jobs. Each rule has an id, a Go-template match expression that decides whether the rule applies to the device, and an optional config_template that renders the collector job YAML when the rule matches.
The default rule shipped with Netdata ({{ true }}) creates one job per discovered device and handles both SNMPv2 and SNMPv3 — most users never change it. Customise rules when you want vendor-specific configs (Cisco vs. Juniper, printers vs. routers), per-VLAN overrides, or multiple jobs per device.
The shared rule model — function reference (sprig + Netdata helpers match, glob, promPort, toYaml), config_template rendering rules, and the strict-missing-key error semantics — lives on the Service Discovery hub page. The notes below are SNMP-specific.
Quick reference — see Rule evaluation semantics on the hub page for the full model (sequence-output multi-job rendering, module inference from id, missingkey=error, ordering recommendations).
config_template drops the device immediately — no job, no further rule evaluation. Use it to exclude devices the catch-all would otherwise pick up. Place before any template rule.config_template produces one or more jobs and rule evaluation continues. A single device can therefore produce jobs from several matching rules.id: snmp so the rendered job inherits the snmp module name automatically, or include module: snmp explicitly inside the config_template (required when id is anything else, e.g. cisco).Available inside both match expressions and config_template bodies. All variables are strings; empty values render as the empty string.
| Variable | Type | Description |
|---|---|---|
.IPAddress | string | IP address of the discovered device. Always set. |
.SysInfo.Descr | string | Value of sysDescr.0 (vendor-supplied free-form description). May be empty. |
.SysInfo.Contact | string | Value of sysContact.0. May be empty. |
.SysInfo.Name | string | Value of sysName.0 (typically the device hostname or FQDN). Defaults to the literal string unknown when the device does not return one. |
.SysInfo.Location | string | Value of sysLocation.0. May be empty. |
.SysInfo.Organization | string | Vendor or organization parsed from sysObjectID against the bundled enterprise-numbers table. Defaults to Unknown when the OID is not in the table. |
.SysInfo.Vendor | string | Vendor name inferred from sysObjectID and sysDescr via the bundled overrides. Empty when no override matches. |
.SysInfo.Category | string | Device category (e.g. router, switch, printer). Sourced from the bundled SNMP overrides; empty when no override matches the device. The set of category values is determined by the overrides, not a closed enum. |
.SysInfo.Model | string | Device model inferred from sysObjectID and sysDescr via the bundled overrides. Empty when no override matches. |
.Credential.Name | string | Name of the credential entry that successfully probed the device. |
.Credential.Version | string | Configured version string: 1, 2, 2c, or 3. Use eq .Credential.Version "1" "2" "2c" to branch v1/v2c vs v3. |
.Credential.Community | string | Community string (SNMPv1/v2c). Empty for SNMPv3. |
.Credential.UserName | string | SNMPv3 USM user name. Empty for v1/v2c. |
.Credential.SecurityLevel | string | SNMPv3 security level (noAuthNoPriv, authNoPriv, authPriv). |
.Credential.AuthProtocol | string | SNMPv3 auth protocol (md5, sha, sha224–sha512). |
.Credential.AuthPassphrase | string | SNMPv3 authentication passphrase. YAML key for the same value: auth_password (see credentials option). |
.Credential.PrivacyProtocol | string | SNMPv3 privacy protocol (des, aes, aes192, aes256, aes192c, aes256c). |
.Credential.PrivacyPassphrase | string | SNMPv3 privacy passphrase. YAML key for the same value: priv_password (see credentials option). |
Each example shows one or more entries from the services: array. Order matters — see How rules are evaluated.
Generate one snmp collector job per discovered device. This is the rule produced by the stock conf and is sufficient for most deployments — it handles both SNMPv2 and SNMPv3 by branching on .Credential.Version. The id: snmp makes the module name infer to snmp automatically.
- id: snmp
match: '{{ true }}'
config_template: |
{{- if .SysInfo.Name }}
name: {{ .SysInfo.Name }}-ip-{{ .IPAddress }}
{{- else }}
name: ip-{{ .IPAddress }}
{{- end }}
hostname: {{ .IPAddress }}
options:
version: {{ .Credential.Version }}
{{- if eq .Credential.Version "1" "2" "2c" }}
community: {{ .Credential.Community }}
{{- else }}
user:
name: {{ .Credential.UserName }}
level: {{ .Credential.SecurityLevel }}
auth_proto: {{ .Credential.AuthProtocol }}
auth_key: {{ .Credential.AuthPassphrase }}
priv_proto: {{ .Credential.PrivacyProtocol }}
priv_key: {{ .Credential.PrivacyPassphrase }}
{{- end }}
Drop devices whose sysName starts with vip- so they are not monitored. A skip rule is a rule with no config_template. Place it before the catch-all so its match wins first. (The second rule below is the Default catch-all rule — paste its full body in place of the placeholder comment.)
- id: skip-vips
match: '{{ glob .SysInfo.Name "vip-*" }}'
- id: snmp
match: '{{ true }}'
config_template: |
# paste the body from the "Default catch-all rule" example here
Apply a Cisco-specific config to devices whose vendor matches Cisco*, then prevent the catch-all from producing a duplicate job for the same devices. This is the recommended three-rule pattern for any vendor-specific override:
cisco) — renders the Cisco-tuned job. id: cisco does not map to a real collector module, so module: snmp is set explicitly in the template.skip-cisco-from-catchall) — drops Cisco devices from the remaining pipeline so step 3 does not also fire for them.snmp) — handles every non-Cisco device.- id: cisco
match: '{{ glob .SysInfo.Vendor "Cisco*" }}'
config_template: |
module: snmp
name: cisco-{{ .SysInfo.Name }}-{{ .IPAddress }}
hostname: {{ .IPAddress }}
options:
version: {{ .Credential.Version }}
{{- if eq .Credential.Version "1" "2" "2c" }}
community: {{ .Credential.Community }}
{{- else }}
user:
name: {{ .Credential.UserName }}
level: {{ .Credential.SecurityLevel }}
auth_proto: {{ .Credential.AuthProtocol }}
auth_key: {{ .Credential.AuthPassphrase }}
priv_proto: {{ .Credential.PrivacyProtocol }}
priv_key: {{ .Credential.PrivacyPassphrase }}
{{- end }}
- id: skip-cisco-from-catchall
match: '{{ glob .SysInfo.Vendor "Cisco*" }}'
- id: snmp
match: '{{ true }}'
config_template: |
# ... (same as the catch-all in the Default catch-all rule example above)
Match by .SysInfo.Category to apply a printer-specific config. Category values are populated from the bundled SNMP overrides — printer is one of the standard categories produced by the override file shipped with Netdata. Pair with a follow-up skip rule the same way as the Cisco example if you want to suppress the catch-all for printers.
- id: hp-printer
match: '{{ and (eq .SysInfo.Category "printer") (glob .SysInfo.Vendor "HP*" "Hewlett*") }}'
config_template: |
module: snmp
name: printer-{{ .SysInfo.Name }}-{{ .IPAddress }}
hostname: {{ .IPAddress }}
update_every: 30
options:
version: {{ .Credential.Version }}
community: {{ .Credential.Community }}
After enabling the discoverer, confirm it is finding devices and producing jobs.
Watch the agent log for SNMP discoverer messages. On a successful probe you should see lines like:
discoverer=snmp ... device '192.168.1.10': successfully discovered (sysName: 'sw01.example.com', network: '192.168.1.0/24')
With systemd:
journalctl _SYSTEMD_INVOCATION_ID="$(systemctl show --value --property=InvocationID netdata)" --namespace=netdata --grep "discoverer=snmp"
Without systemd:
grep "discoverer=snmp" /var/log/netdata/collector.log
Discovered devices should produce snmp collector jobs. In the Netdata UI go to Collectors -> go.d -> snmp — each discovered device appears as a job named according to your config_template (the default catch-all renders <sysName>-ip-<address>).
Once a job exists, the snmp collector takes over and starts collecting metrics. Charts for each device appear under the SNMP integration on the dashboard. If a job is created but metrics never appear, the problem is in the snmp collector configuration (rendered by your config_template), not in the discoverer.
Check the agent log for discoverer=snmp messages. Common causes:
ping / arp from the Netdata host.nc -zu <ip> 161 or snmpwalk -v2c -c <community> <ip> sysDescr.0.authentication failure or decryption error log lines.subnet '...' exceeds maximum size of /23 in the log.Rule order matters — see How rules are evaluated. Place vendor-specific or device-specific rules before the catch-all. If you need to suppress the catch-all for a subset of devices, follow the specific rule with a skip rule (no config_template) keyed on the same condition.
The discoverer creates jobs but does not run them — the snmp collector does. Check the snmp collector log and the rendered job YAML in the agent's debug output. Common causes:
config_template produces invalid YAML for some discovered field values (for example, unescaped colons in sysName). YAML-quote dynamic values when in doubt.id (or explicit module: field) does not match snmp.system MIB during discovery but the collector cannot read other OIDs (different VACM view); confirm with snmpwalk against the device.