<!--startmeta
custom_edit_url: "https://github.com/netdata/netdata/edit/master/src/go/plugin/go.d/collector/snmp_traps/README.md"
meta_yaml: "https://github.com/netdata/netdata/edit/master/src/go/plugin/go.d/collector/snmp_traps/metadata.yaml"
sidebar_label: "SNMP trap listener"
learn_status: "Published"
learn_rel_path: "Network Performance Monitoring/SNMP Traps/Integrations"
keywords: ['snmp', 'trap', 'inform', 'snmpv3', 'usm', 'syslog', 'network events', 'event monitoring', 'notifications', 'fault management', 'network management']
message: "DO NOT EDIT THIS FILE DIRECTLY, IT IS GENERATED BY THE COLLECTOR'S metadata.yaml FILE"
endmeta-->

<!-- markdownlint-disable-file -->
# SNMP trap listener


<img src="https://netdata.cloud/img/SNMP.png" width="150"/>


Plugin: go.d.plugin
Module: snmp_traps

<img src="https://img.shields.io/badge/maintained%20by-Netdata-%2300ab44" />

## Overview

This collector listens for incoming SNMP Trap and INFORM notifications from network devices and persists them as enriched, structured log entries.

- **Multi-protocol**: Accepts SNMPv1 Trap, SNMPv2c Trap/INFORM, and SNMPv3 Trap/INFORM with USM (user-based security model) authentication and privacy.
- **Per-job listeners**: Each job binds UDP endpoints independently, enabling per-site or per-segment trap receivers.
- **OOB profile pack**: Netdata ships with a library of pre-built trap profiles that resolve numeric OIDs to names, categories, severities, and varbind labels without manual MIB work for common equipment.
- **Dynamic engine ID discovery**: Optional runtime discovery of SNMPv3 sender engine IDs for environments where the engine ID is not known in advance.
- **Deduplication**: Optional configurable per-job dedup that suppresses repeated identical traps within a window. The first matching trap is journaled immediately; subsequent matches increment a summary counter and a periodic summary entry is written.
- **Per-OID overrides**: Operators can override the profile-assigned category, severity, and labels for specific OIDs without editing profiles.
- **Profile-defined trap metrics**: Operators can define trap-to-metric rules in custom trap profiles, then enable selected rules per listener job with `profile_metrics`. Profile metrics are emitted per source device, using vnode host scope when enrichment finds an unambiguous vnode and bounded source labels for chart identity and fallback attribution.
- **Direct journal storage**: Enabled by default for explicit jobs. Stores traps under the configured Netdata log directory (`${NETDATA_LOG_DIR}/traps/<job>/`; package installs usually use `/var/log/netdata`, and static installs commonly use `/opt/netdata/var/log/netdata`) and exposes the embedded `snmp:traps` Function. Direct-journal jobs appear as `__logs_sources` options.
- **OTLP/gRPC export**: Optional backend that exports traps as OTLP LogRecords. When `otlp.enabled` is `true`, traps are exported through OTLP regardless of `journal.enabled`; if direct journal storage is also enabled, both backends receive traps.
- **Self-metrics**: Per-job pipeline counters, trap events (by category and severity), processing errors (by type), dedup suppression (when enabled), and profile-metric diagnostics.

When direct journal storage is enabled, trap entries are written as structured systemd-journal log messages with plugin-controlled fields (`TRAP_REPORT_TYPE`, `TRAP_JOB`, `TRAP_OID`, `TRAP_NAME`, `TRAP_CATEGORY`, `TRAP_SEVERITY`, `TRAP_PDU_TYPE`, `TRAP_VERSION`, `TRAP_SOURCE_IP`, `TRAP_SOURCE_UDP_PEER`, `TRAP_SOURCE_UDP_PORT`, `TRAP_DEVICE_VENDOR`, `TRAP_INTERFACE`, `TRAP_NEIGHBORS`, `TRAP_REVERSE_DNS`, `TRAP_SUPPRESSED_COUNT`, `TRAP_SUPPRESSED_FINGERPRINTS`, `TRAP_REPORT_PERIOD_SEC`, `TRAP_DECODE_ERROR_KIND`, `TRAP_DECODE_ERROR`, `TRAP_PACKET_SIZE`, `TRAP_PACKET_SHA256`, `TRAP_LISTENER`, `TRAP_ENGINE_ID`, `TRAP_ENRICHMENT`, `TRAP_JSON`) plus profile-defined labels (`TRAP_TAG_*`) and decoded event varbind fields (`TRAP_VAR_*`). Non-sensitive, non-redundant event varbinds are indexed as `TRAP_VAR_*`; enum-backed varbinds also emit `_RAW` with the numeric value. `TRAP_ENRICHMENT` records the source-attribution and enrichment decisions for audit/debug, and `TRAP_JSON` stores the structured varbind payload plus `netdata_packet_sequence`, a per-job receive counter assigned once per UDP datagram. Query traps with the embedded `snmp:traps` Function through Netdata Cloud or directly via the Agent HTTP API. The Function selects all direct-journal jobs by default and can narrow to one listener with `selections.__logs_sources=["<job>"]`. OTLP-only jobs do not create local journal files and therefore do not appear as log sources.

**Closed 8-category / 8-severity taxonomy** (from the OOB profile pack):

| Category | Description |
|----------|-------------|
| `state_change` | Link up/down, operational state transitions |
| `config_change` | Configuration modifications |
| `security` | Security events (intrusion, ACL, etc.) |
| `auth` | Authentication and authorization events |
| `license` | License-state events |
| `mobility` | Roaming, handoff, wireless client events |
| `diagnostic` | Tests, health checks, probes |
| `unknown` | Unmatched or unclassified traps |

| Severity | Description |
|----------|-------------|
| `emerg` | System unusable |
| `alert` | Immediate action required |
| `crit` | Critical condition |
| `err` | Error condition |
| `warning` | Warning condition |
| `notice` | Normal but significant condition |
| `info` | Informational |
| `debug` | Debug-level message |


**Profile locations**

| Type | Default path | Notes |
|------|--------------|-------|
| **Stock profiles** | `/usr/lib/netdata/conf.d/go.d/snmp.trap-profiles/default/` | Shipped with Netdata; packages store vendor files as `.yaml.zst` |
| **User profiles** | `/etc/netdata/go.d/snmp.trap-profiles/` | Place custom or converted `.yaml` profiles here |

> Depending on installation, paths may be prefixed with `/opt/netdata`.

A **trap profile** defines per-OID mappings:
- Category and severity
- Trap name and description
- Varbind labels for structured enrichment
- Optional trap-to-metric rules and chart definitions

**At runtime, the collector**:
1. Receives a trap PDU on a bound UDP endpoint
2. Validates the SNMP version, community/USM, and source against the job configuration
3. Resolves the trap OID against operator profiles and lazily-loaded stock profile files to get a name, category, severity, and varbind labels
4. Enriches the entry with optional reverse DNS (`TRAP_REVERSE_DNS` annotation, never `_HOSTNAME`) and dedup logic (if enabled)
5. Writes the structured entry to the per-job direct journal when enabled, and exports via OTLP when configured
6. Updates enabled profile-defined trap metrics only after the trap is committed to the configured backend
7. Increments the per-job self-metrics (events by category and severity, errors by type)

**Custom MIB workflow**: Operators with device-specific MIBs not covered by the OOB profiles can use the installed `/usr/libexec/netdata/plugins.d/snmp-trap-profile-gen` helper to convert MIBs into trap profile YAMLs offline. The helper writes profiles under `snmp-trap-profile-gen-output/profiles/`; copy the needed YAML files to `/etc/netdata/go.d/snmp.trap-profiles/`. Profile files are immutable while any trap job holds a lease on the shared catalog epoch. After changing operator or stock profiles, restart the Agent or recreate all running trap jobs so the final lease release unloads the epoch. The next job initialization eagerly validates operator profiles, the stock manifest and inventory, and each manifest digest's syntax. Stock vendor YAML is loaded only when selected by an exact trap OID, an enabled metric rule, or the candidate-file set for a MIB-qualified trap name; that lazy load verifies the exact decompressed bytes against the digest captured by the epoch before parsing them. See [SNMP trap profile format](https://github.com/netdata/netdata/blob/master/src/go/plugin/go.d/config/go.d/snmp.trap-profiles/profile-format.md) for the YAML schema.

Example conversion for a MIB module not shipped in the OOB pack:
```sh
/usr/libexec/netdata/plugins.d/snmp-trap-profile-gen generate \
  --source-dir /path/to/vendor-mibs \
  --mib NAGIOS-NOTIFY-MIB \
  --out-dir ./snmp-trap-profile-gen-output
```


This collector is supported on all platforms.

This collector supports collecting metrics from multiple instances of this integration, including remote instances.

Binding to the standard SNMP trap port (UDP/162) requires elevated bind privileges on many platforms.
On Linux, this means `CAP_NET_BIND_SERVICE` or root. Netdata packages grant this capability to `go.d.plugin` and allow it in `netdata.service`.


### Default Behavior

#### Auto-Detection

SNMP trap collection is not auto-detected. The collector must be explicitly configured as a job under `go.d/snmp_traps.conf`.


#### Limits

BER decode limits protect the UDP-exposed parser: datagrams are capped at 8 KiB, varbinds at 256 per PDU, BER nesting depth at 8, encoded OID length at 128 bytes, and OctetString values at 1024 bytes.
Accepted-source decode failures are written as `TRAP_REPORT_TYPE=decode_error` rows with sanitized error details, source address/port, listener endpoint when known, sniffed SNMP version when known, packet size, and packet SHA-256. Raw packet bytes are not written because SNMP community strings and binary payloads can appear in received datagrams.
Deduplication, when enabled, uses a per-job fingerprint cache capped by `dedup.cache_max_entries` (default 100000).


#### Performance Impact

The collector is event-driven and does not poll devices. CPU cost is proportional to the received trap rate.
Profile OID lookups use hash tables. Deduplication, when enabled, adds a configurable fingerprint cache.
For high-volume environments, size the dedup cache and journal rotation according to sustained trap volume and retention requirements. OTLP-only jobs avoid local journal storage but do not appear as sources in the embedded local logs viewer.


## Setup


You can configure the **snmp_traps** collector in two ways:

| Method                | Best for                                                                                 | How to                                                                                                                                 |
|-----------------------|------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
| [**UI**](#via-ui)     | Fast setup without editing files                                                         | Go to **Nodes → Configure this node → Collectors → Jobs**, search for **snmp_traps**, then click **+** to add a job. |
| [**File**](#via-file) | If you prefer configuring via file, or need to automate deployments (e.g., with Ansible) | Edit `go.d/snmp_traps.conf` and add a job.                                                                        |

:::important

UI configuration requires paid Netdata Cloud plan.

:::


### Prerequisites

#### Prepare SNMP trap sources

Configure the network devices sending traps:
- Set the trap destination to the Netdata host's IP address and the UDP port bound by the listener job.
- Ensure the SNMP community (v1/v2c) or USM credentials (v3) match the job configuration.
- For v3 traps, configure the device's engine ID and USM user with the matching auth and privacy protocols.


#### Verify Netdata log directory access

Direct-journal jobs write under the configured Netdata log directory (`${NETDATA_LOG_DIR}/traps/`). Package installs usually use `/var/log/netdata`; static installs commonly use `/opt/netdata/var/log/netdata`.
Job creation fails if the configured Netdata log directory is missing or unusable. For OTLP-only jobs, set `journal.enabled: false` and `otlp.enabled: true`.


#### Add custom trap profiles (optional)

If the stock trap profiles do not cover a device, convert vendor MIBs with the installed `/usr/libexec/netdata/plugins.d/snmp-trap-profile-gen` helper and place the resulting YAML profiles under `/etc/netdata/go.d/snmp.trap-profiles/`.
This is the supported workflow for adding custom trap profile coverage.
Profile YAML syntax is documented in [SNMP trap profile format](https://github.com/netdata/netdata/blob/master/src/go/plugin/go.d/config/go.d/snmp.trap-profiles/profile-format.md).



### Configuration

#### Options

The following options can be defined globally: update_every, autodetection_retry.


<details open><summary>Config options</summary>



| Group | Option | Description | Default | Required |
|:------|:-----|:------------|:--------|:---------:|
| **Collection** | update_every | Framework collection interval for self-metrics. Trap packet reception is event-driven and does not depend on this interval. | 1 | no |
| **Listener** | [listen](#option-listener-listen) | Network endpoints this listener binds during job creation. |  | yes |
| **SNMP** | [versions](#option-snmp-versions) | Accepted trap protocol versions. | [v1, v2c] | no |
| **SNMPv1/2c** | communities | SNMPv1/v2c community allowlist. Empty accepts all communities. | [] | no |
| **SNMPv3** | [usm_users](#option-snmpv3-usm-users) | SNMPv3 USM users with auth and privacy protocols. | [] | no |
|  | engine_id_whitelist | Static SNMPv3 engine IDs accepted for v3 Trap PDUs (hex strings). Required when v3 is enabled and `dynamic_engine_id_discovery` is disabled. | [] | no |
|  | local_engine_id | Receiver-local SNMPv3 engine ID for v3 INFORM authentication (hex string, 5-32 bytes). When omitted, Netdata generates and persists a stable per-job value. |  | no |
|  | dynamic_engine_id_discovery | When enabled, the listener discovers v3 Trap sender engine IDs at runtime and hot-registers new (engineID, username) pairs after the retry authenticates and decodes a v3 Trap. Static `engine_id_whitelist` must be empty. | no | no |
|  | dynamic_engine_id_max_pairs | Maximum in-memory dynamic (engineID, username) pairs per job. 0 or unset uses the default of 4096. | 4096 | no |
| **Enrichment** | reverse_dns | Optional source-IP PTR annotation emitted as `TRAP_REVERSE_DNS`. Disabled by default and not used for authoritative identity. | enabled: false | no |
| **Security** | [source](#option-security-source) | Source-attribution controls for forwarded traps. UDP peer is authoritative unless the peer matches an explicit trusted relay CIDR. | trusted_relays: [] | no |
|  | allowlist | Pre-decode source-IP CIDR allowlist. Empty accepts IPv4 and IPv6 from all sources. | source_cidrs: ["0.0.0.0/0", "::/0"] | no |
| **Rate limiting** | [rate_limit](#option-rate-limiting-rate-limit) | Per-source token-bucket rate limiting. Default off. |  | no |
| **Deduplication** | [dedup](#option-deduplication-dedup) | Optional per-job trap deduplication. Disabled by default. |  | no |
| **Direct journal** | [journal](#option-direct-journal-journal) | Direct local journal storage for received traps. Enabled by default for explicit jobs. | enabled: true | no |
| **OTLP export** | [otlp](#option-otlp-export-otlp) | Optional backend that exports traps as OTLP/gRPC LogRecords. Disabled by default. |  | no |
| **Retention** | [retention](#option-retention-retention) | Per-job direct journal retention and rotation policy. Ignored when `journal.enabled` is `false`. |  | no |
| **Overrides** | [overrides](#option-overrides-overrides) | Per-OID category, severity, and label overrides on top of profile defaults. | [] | no |
| **Profile metrics** | [profile_metrics](#option-profile-metrics-profile-metrics) | Enable and select trap-to-metric rules defined by loaded trap profiles. | enabled: false | no |
| **Virtual node** | vnode | Associates this trap listener job with a Virtual Node. |  | no |

<a id="option-listener-listen"></a>
##### listen

- `receive_buffer`: UDP socket receive buffer requested during job creation, in bytes (default 4194304; set 0 to keep the operating system default; maximum 268435456).
Each endpoint has:
- `protocol`: Transport protocol (`udp` only).
- `address`: Local IP address to bind (e.g., `0.0.0.0` for all interfaces).
- `port`: UDP port number (default 162). Port 162 requires `CAP_NET_BIND_SERVICE` or root.


<a id="option-snmp-versions"></a>
##### versions

Supported values: `v1`, `v2c`, `v3`. All three can be combined.


<a id="option-snmpv3-usm-users"></a>
##### usm_users

Each user has:
- `username`: SNMPv3 USM security name (required).
- `engine_id`: Authoritative engine ID in hex (e.g., `80001f8880e5a5c0d6c7b8a9`). Required for static v3 jobs. May be omitted when `dynamic_engine_id_discovery` is enabled.
- `auth_proto`: Authentication protocol (`none`, `md5`, `sha`, `sha224`, `sha256`, `sha384`, `sha512`).
- `auth_key`: Authentication passphrase (use a Netdata secret reference). Required when `auth_proto` is not `none`; minimum 8 characters.
- `priv_proto`: Privacy protocol (`none`, `des`, `aes`, `aes192`, `aes256`, `aes192c`, `aes256c`).
- `priv_key`: Privacy passphrase (use a Netdata secret reference). Required when `priv_proto` is not `none`; minimum 8 characters.


<a id="option-security-source"></a>
##### source

- `trusted_relays`: CIDR list of SNMP trap relays/proxies whose `snmpTrapAddress.0` PDU source address may override the UDP peer. Leave empty for direct listeners.


<a id="option-rate-limiting-rate-limit"></a>
##### rate_limit

- `enabled`: Enable per-source rate limiting (default `false`).
- `per_source_pps`: Maximum traps per second from a single source IP (default 1000).
- `mode`: Action when exceeded — `drop` (discard trap) or `sample` (allow but count as `rate_limited`).


<a id="option-deduplication-dedup"></a>
##### dedup

- `enabled`: Enable dedup (default `false`).
- `window_sec`: Dedup window in seconds (default 5).
- `cache_max_entries`: Maximum fingerprints kept in memory (default 100000).
- `key_varbinds`: Additional varbind names to include in the dedup fingerprint (default `[]`, fingerprint is source device + trap OID only).


<a id="option-direct-journal-journal"></a>
##### journal

- `enabled`: Write traps to local direct journal files under the configured Netdata log directory (`${NETDATA_LOG_DIR}/traps/<job>/`) and expose the job as a `__logs_sources` option in the embedded `snmp:traps` Function. Package installs usually use `/var/log/netdata`; static installs commonly use `/opt/netdata/var/log/netdata`.
- Set `enabled: false` only when another output backend, such as OTLP, is enabled.


<a id="option-otlp-export-otlp"></a>
##### otlp

- `enabled`: Enable OTLP/gRPC Logs export. When `true`, traps are exported through OTLP regardless of `journal.enabled`; if direct journal storage is also enabled, both backends receive traps.
- `endpoint`: OTLP/gRPC endpoint. `http://host:port` uses plaintext gRPC; `https://host:port` uses TLS (default `http://127.0.0.1:4317`). Use `https://` for remote collectors when trap contents should be protected in transit.
- `headers`: Optional OTLP metadata headers (values may use Netdata secret references).
- `request_timeout`: Timeout for connection preflight and export calls (default `5s`).
- `flush_interval`: Maximum time to buffer records before export (default `200ms`).
- `batch_size`: Maximum LogRecords per export request (default 512).
- `queue_capacity`: Maximum records buffered per job (default 10000).


<a id="option-retention-retention"></a>
##### retention

- `max_size`: Maximum total bytes across all journal files (default `10GB`). Set `null` to disable size-based eviction.
- `max_duration`: Maximum age of the oldest journal file before deletion (default `null`, age-based eviction disabled).
- `rotation_size`: Maximum size of a single journal file before rotation (default `null` = auto, `max_size/20` clamped 5MB-200MB).
- `rotation_duration`: Maximum age of a single journal file before rotation (default `null`, time-based rotation disabled). Set a duration such as `24h` to enable time-based rotation.


<a id="option-overrides-overrides"></a>
##### overrides

Each override entry requires an `oid` (numeric OID). Optional fields: `category` (one of the 8 categories), `severity` (one of the 8 severities), `labels` (free-form key-value pairs).


<a id="option-profile-metrics-profile-metrics"></a>
##### profile_metrics

- `enabled`: Enable profile-defined trap metrics for committed traps (default `false`).
- `include`: Explicit metric rule names to enable. At least one rule is required when `enabled` is `true`.
- Device-attributable metrics use vnode host scope when enrichment finds an unambiguous vnode. Otherwise they use a bounded, hashed source label under the listener job.
- Cardinality limits and overflow handling are fixed safety policies. Over-cap metric instances are skipped, accepted traps are still committed, and profile metric diagnostics increment.
- Define custom rules in files under `/etc/netdata/go.d/snmp.trap-profiles/` with profile `metrics:` and `charts:` sections. See the SNMP trap profile format documentation for rule syntax and examples.



</details>


#### via UI

Configure the **snmp_traps** collector from the Netdata web interface:

1. Go to **Nodes**.
2. Select the node **where you want the snmp_traps data-collection job to run** and click the :gear: (**Configure this node**). That node will run the data collection.
3. The **Collectors → Jobs** view opens by default.
4. In the Search box, type _snmp_traps_ (or scroll the list) to locate the **snmp_traps** collector.
5. Click the **+** next to the **snmp_traps** collector to add a new job.
6. Fill in the job fields, then click **Test** to verify the configuration and **Submit** to save.
    - **Test** runs the job with the provided settings and shows whether data can be collected.
    - If it fails, an error message appears with details (for example, connection refused, timeout, or command execution errors), so you can adjust and retest.


#### via File

The configuration file name for this integration is `go.d/snmp_traps.conf`.

The file format is YAML. Generally, the structure is:

```yaml
update_every: 1
autodetection_retry: 0
jobs:
  - name: some_name1
  - name: some_name2
```
You can edit the configuration file using the [`edit-config`](https://github.com/netdata/netdata/blob/master/docs/netdata-agent/configuration/README.md#edit-configuration-files) script from the
Netdata [config directory](https://github.com/netdata/netdata/blob/master/docs/netdata-agent/configuration/README.md#locate-your-config-directory).

```bash
cd /etc/netdata 2>/dev/null || cd /opt/netdata/etc/netdata
sudo ./edit-config go.d/snmp_traps.conf
```

##### Examples

###### Basic (SNMPv1/v2c)

A single job listening on the standard trap port. Accepts any SNMPv1/v2c community.
The allowlist is left open (`0.0.0.0/0` and `::/0`) — restrict it for production.


<details open><summary>Config</summary>

```yaml
jobs:
  - name: local
    listen:
      receive_buffer: 4194304
      endpoints:
        - protocol: udp
          address: 0.0.0.0
          port: 162
    versions:
      - v1
      - v2c

```
</details>

###### OTLP-only export

A job that disables direct journal creation and exports traps only through OTLP.
This job does not appear as a local `__logs_sources` option because no direct journal files are written.


<details open><summary>Config</summary>

```yaml
jobs:
  - name: local-otel
    listen:
      endpoints:
        - protocol: udp
          address: 0.0.0.0
          port: 162
    journal:
      enabled: false
    otlp:
      enabled: true
      endpoint: "http://127.0.0.1:4317"

```
</details>

###### SNMPv3 with static USM

A job accepting v3 traps from a known device. The USM user has a static engine ID,
and the engine ID whitelist is explicitly set. Auth and privacy keys use Netdata secret references.


<details open><summary>Config</summary>

```yaml
jobs:
  - name: core-router
    listen:
      endpoints:
        - protocol: udp
          address: 0.0.0.0
          port: 162
    versions:
      - v3
    usm_users:
      - username: trapmon
        engine_id: 80001f8880e5a5c0d6c7b8a9
        auth_proto: sha256
        auth_key: "${env:SNMP_V3_AUTH_KEY}"
        priv_proto: aes
        priv_key: "${env:SNMP_V3_PRIV_KEY}"
    engine_id_whitelist:
      - 80001f8880e5a5c0d6c7b8a9

```
</details>

###### Dynamic engine ID discovery

For environments where v3 sender engine IDs are not known in advance.
The listener discovers them at runtime from raw SNMPv3 context and hot-registers
new (engineID, username) pairs after the first successful authentication and decode.
The USM user omits `engine_id`; the whitelist must be empty.


<details open><summary>Config</summary>

```yaml
jobs:
  - name: dynamic-v3
    listen:
      endpoints:
        - protocol: udp
          address: 0.0.0.0
          port: 162
    versions:
      - v3
    usm_users:
      - username: trapmon
        auth_proto: sha256
        auth_key: "${env:SNMP_V3_AUTH_KEY}"
        priv_proto: aes
        priv_key: "${env:SNMP_V3_PRIV_KEY}"
    dynamic_engine_id_discovery: true
    dynamic_engine_id_max_pairs: 4096

```
</details>

###### With dedup

A job with dedup enabled (window 10 seconds).


<details open><summary>Config</summary>

```yaml
jobs:
  - name: campus-core
    listen:
      endpoints:
        - protocol: udp
          address: 0.0.0.0
          port: 162
    dedup:
      enabled: true
      window_sec: 10

```
</details>

###### Custom profile metric rule

A custom trap profile can define metric rules and charts. The listener job then enables those rules with `profile_metrics`.
This example counts committed Cisco configuration change traps per source device. With the default `identity.device: source`, metrics use vnode host scope when enrichment finds an unambiguous vnode and hashed fallback `source_id` labels otherwise.
The rule can reference a trap already defined by the stock profiles by using its MIB-qualified trap name in `on_trap`.


<details open><summary>Config</summary>

```yaml
# /etc/netdata/go.d/snmp.trap-profiles/site-cisco.yaml
metrics:
  - name: cisco.config.changed
    type: counter
    on_trap: CISCO-CONFIG-MAN-MIB::ccmCLIRunningConfigChanged
    output:
      metric: snmp_trap_cisco_config_events
      dimension: changes
      chart: cisco_config_changes
charts:
  - id: cisco_config_changes
    title: Cisco configuration changes
    context: snmp.trap.cisco.config.changes
    units: events/s
    algorithm: incremental

# /etc/netdata/go.d/snmp_traps.conf
jobs:
  - name: campus-core
    listen:
      endpoints:
        - protocol: udp
          address: 0.0.0.0
          port: 162
    profile_metrics:
      enabled: true
      include:
        - cisco.config.changed

```
</details>



## Alerts


The following alerts are available:

| Alert name  | On metric | Description |
|:------------|:----------|:------------|
| [ snmp_trap_emergency_events ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.severity | The SNMP trap listener is receiving emergency-severity traps. |
| [ snmp_trap_alert_events ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.severity | The SNMP trap listener is receiving alert-severity traps that require immediate attention on the sending device. |
| [ snmp_trap_critical_events ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.severity | The SNMP trap listener is receiving critical-severity traps. |
| [ snmp_trap_error_events ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.severity | The SNMP trap listener is receiving error-severity traps at high rate. |
| [ snmp_trap_warning_event_storm ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.severity | The SNMP trap listener is receiving warning-severity traps at storm-level rate. |
| [ snmp_trap_decode_errors ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener has decode errors. |
| [ snmp_trap_template_unresolved ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener received traps whose profile templates referenced missing varbinds or fields. |
| [ snmp_trap_malformed_pdus ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener is receiving structurally invalid trap PDUs. |
| [ snmp_trap_allowlist_drops ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener is dropping traps because the sender IP is outside the configured allowlist. |
| [ snmp_trap_rate_limited ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener is receiving traps above the configured per-source rate limit. |
| [ snmp_trap_auth_failures ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener has authentication failures. |
| [ snmp_trap_usm_failures ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener has USM failures. |
| [ snmp_trap_unknown_engine_id ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener is receiving v3 traps from engine IDs outside the static whitelist, or first-time dynamic engine ID registrations when dynamic discovery is enabled. |
| [ snmp_trap_inform_response_failures ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener failed to send INFORM acknowledgements back to senders. |
| [ snmp_trap_binary_encoded_fields ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener wrote structured fields with binary journal encoding. |
| [ snmp_trap_profile_load_failures ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener failed to load trap profiles. |
| [ snmp_trap_journal_write_failures ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener failed to write traps to the systemd-journal. |
| [ snmp_trap_otlp_export_failures ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener failed to export traps through OTLP. |
| [ snmp_trap_listener_read_failures ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.errors | The SNMP trap listener failed to read UDP packets from a bound socket. |
| [ snmp_trap_high_dedup_suppression ](https://github.com/netdata/netdata/blob/master/src/health/health.d/snmp_traps.conf) | snmp.trap.dedup_suppressed | The SNMP trap listener is suppressing a high volume of duplicate traps. |



## Metrics

Metrics grouped by *scope*.

The scope defines the instance that the metric belongs to. An instance is uniquely identified by a set of labels.

Built-in receiver metrics keep per-job totals with the `job_name` label so listener health remains visible even when a packet cannot be attributed to a source device.

Profile-defined trap metrics are emitted dynamically when `profile_metrics` enables rules from loaded trap profiles. Device-attributable profile metrics use vnode host scope when enrichment finds an unambiguous vnode; all profile metric series also include bounded `source_id` and `source_kind` labels so generated chart instances keep a stable identity. Resource metrics additionally include `resource_class` and `resource_id`. When vnode enrichment is unavailable, ambiguous, or conflicting, profile metrics use those labels under the listener job.

`accepted` is recorded before dedup suppression. `committed`, event/severity counters, and profile-defined metrics are recorded only after successful authoritative output commitment. When both journal and OTLP outputs are enabled, journal is authoritative for commitment and OTLP export failures increment the `otlp_export_failed` error counter. When OTLP is the only output backend, OTLP export failures are terminal write failures and also increment `pipeline.write_failed`.

**Built-in contexts:**

- `snmp.trap.pipeline`: Receiver packet and write pipeline progress, grouped per job.
- `snmp.trap.events`: Trap events received, split by category. The `stacked` chart type gives a visual burst profile across categories.
- `snmp.trap.severity`: Trap events received, split by severity. The `stacked` chart type gives a visual burst profile across the closed 8-severity taxonomy (`emerg`, `alert`, `crit`, `err`, `warning`, `notice`, `info`, `debug`).
- `snmp.trap.errors`: Processing errors by type. Stacked chart for quick identification of dominant error categories.
- `snmp.trap.dedup_suppressed`: Per-second rate of traps suppressed by dedup (only emitted when dedup is enabled on the job).
- `snmp.trap.profile_metric_diagnostics`: Profile-defined trap metric extraction and attribution diagnostics (only emitted when `profile_metrics` selects at least one rule).

**Dynamic contexts** (profile metrics):

Trap profiles may define optional `metrics:` rules and `charts:`. Jobs enable rules explicitly with `profile_metrics.enabled` and `profile_metrics.include`. Profile metric contexts are generated at runtime from the profile chart definitions under the `snmp.trap.` context namespace. Profile rules can create counters, last trap-reported numeric samples, and trap-derived state gauges. They are updated only after the trap is successfully committed to the authoritative output backend.



### Per job

Per-job self-metrics for a SNMP trap listener job.

Labels:

| Label      | Description     |
|:-----------|:----------------|
| job_name | The job name as defined in `go.d/snmp_traps.conf`. |

Metrics:

| Metric | Description | Dimensions | Unit |
|:------|:------------|:----------|:----|
| snmp.trap.pipeline | SNMP trap receiver pipeline progress by job | received, decoded, accepted, committed, dedup_suppressed, dropped, write_failed | events/s |
| snmp.trap.events | SNMP trap events received, categorized by type | state_change, config_change, security, auth, license, mobility, diagnostic, unknown | events/s |
| snmp.trap.severity | SNMP trap events received, categorized by severity | emerg, alert, crit, err, warning, notice, info, debug | events/s |
| snmp.trap.errors | SNMP trap processing errors by type | unknown_oid, decode_failed, template_unresolved, malformed_pdu, dropped_allowlist, rate_limited, auth_failures, usm_failures, unknown_engine_id, inform_response_failed, binary_encoded, profile_load_failed, journal_write_failed, otlp_export_failed, listener_read_failed, listener_buffer_degraded | errors/s |
| snmp.trap.dedup_suppressed | Per-second rate of traps suppressed by deduplication (only emitted when dedup is enabled) | suppressed | events/s |
| snmp.trap.profile_metric_diagnostics | Profile-defined trap metric extraction and attribution diagnostics (only emitted when profile_metrics selects at least one rule) | rule_missed, extraction_failed, attribution_failed, overflow_dropped, source_transitions | events/s |



## Troubleshooting

### Debug Mode

**Important**: Debug mode is not supported for data collection jobs created via the UI using the Dyncfg feature.

To troubleshoot issues with the `snmp_traps` collector, run the `go.d.plugin` with the debug option enabled. The output
should give you clues as to why the collector isn't working.

- Navigate to the `plugins.d` directory, usually at `/usr/libexec/netdata/plugins.d/`. If that's not the case on
  your system, open `netdata.conf` and look for the `plugins` setting under `[directories]`.

  ```bash
  cd /usr/libexec/netdata/plugins.d/
  ```

- Switch to the `netdata` user.

  ```bash
  sudo -u netdata -s
  ```

- Run the `go.d.plugin` to debug the collector:

  ```bash
  ./go.d.plugin -d -m snmp_traps
  ```

  To debug a specific job:

  ```bash
  ./go.d.plugin -d -m snmp_traps -j jobName
  ```

### Getting Logs

If you're encountering problems with the `snmp_traps` collector, follow these steps to retrieve logs and identify potential issues:

- **Run the command** specific to your system (systemd, non-systemd, or Docker container).
- **Examine the output** for any warnings or error messages that might indicate issues.  These messages should provide clues about the root cause of the problem.

#### System with systemd

Use the following command to view logs generated since the last Netdata service restart:

```bash
journalctl _SYSTEMD_INVOCATION_ID="$(systemctl show --value --property=InvocationID netdata)" --namespace=netdata --grep snmp_traps
```

#### System without systemd

Locate the collector log file, typically at `/var/log/netdata/collector.log`, and use `grep` to filter for collector's name:

```bash
grep snmp_traps /var/log/netdata/collector.log
```

**Note**: This method shows logs from all restarts. Focus on the **latest entries** for troubleshooting current issues.

#### Docker Container

If your Netdata runs in a Docker container named "netdata" (replace if different), use this command:

```bash
docker logs netdata 2>&1 | grep snmp_traps
```

### Port binding fails (permission denied)

Standard SNMP trap port (UDP/162) requires `CAP_NET_BIND_SERVICE`.

Netdata packages grant this capability to `go.d.plugin` automatically. If running from source
or in a custom deployment, grant it manually:
```bash
sudo setcap CAP_NET_BIND_SERVICE=eip /usr/libexec/netdata/plugins.d/go.d.plugin
```
Alternatively, use a port >= 1024 (e.g., `1062`) and redirect traffic through a firewall.


### SNMPv3 traps not decoded (unknown_engine_id)

In static mode, the sender engine ID is not in `engine_id_whitelist`. Add the sender engine ID
to the whitelist, or switch to `dynamic_engine_id_discovery: true` with an empty whitelist.

In dynamic mode, the first accepted `(engineID, username)` pair increments this once as
operator visibility. Repeated or rejected increments usually indicate cap exhaustion,
invalid sender state, or an unauthorized sender.


### USM authentication failures

Check that the USM user's `auth_proto`, `auth_key`, `priv_proto`, and `priv_key` match the
sender device's configuration. Verify engine ID matches. Use Netdata secret references for keys.


### journal retention eating disk space

The default direct journal retention uses size-based eviction (`max_size: 10GB`) with no time-based age limit.
For high-trap environments, reduce `max_size` or enable `max_duration` to age-out old entries.
OTLP-only jobs can set `journal.enabled: false`; they do not create local journal files and do not appear as sources in the local logs Function.
