sensors

Custom SNMP OIDs: extend, pass & AgentX (How-To)

Expose a script's output over SNMP using the net-snmp extend directive, read under the NET-SNMP-EXTEND-MIB.

By the SNMP Monitoring team · Reviewed July 2026

Sometimes the metric you need simply isn't in any MIB — a queue depth from your app, the output of a health-check script, a business number only your box knows. Net-SNMP lets you expose anything a command can print over SNMP, so your existing poller reads it like any other OID. This page is the paste-ready reference for the three ways to do it — extend, pass/pass_persist, and AgentX — with real snmpd.conf syntax and a working example.

Related: AgentX architecture, enterprise OIDs, and snmpd.conf setup. Hubs: sensors, all OIDs.

Three ways to add custom OIDs

Net-SNMP gives you three mechanisms, in rough order of complexity:

MethodBest forOutput appears under
extendRunning a script and reading its outputNET-SNMP-EXTEND-MIB
pass / pass_persistOwning a whole OID subtree with a scriptThe subtree you register
AgentXCompiled/persistent subagentsWherever the subagent registers

For most "expose a script's output" needs, extend is the right tool — simplest to set up and read. Reach for pass when you want to own a subtree and answer arbitrary OIDs within it, and AgentX when you're writing a real subagent module.

Using extend

The extend directive runs a command and publishes its output under the NET-SNMP-EXTEND-MIB at 1.3.6.1.4.1.8072.1.3.2. The steps:

  1. Write a script that prints your metric to stdout.
  2. Add an extend line to snmpd.conf naming it and pointing at the script.
  3. Restart or reload snmpd.
  4. Read the result under nsExtendOutputLine.

A minimal snmpd.conf entry:

extend queuedepth /usr/local/bin/queue_depth.sh

The named result (queuedepth) shows up in the extend output table. The first line of output is available as nsExtendOutputLine.1 under the extend subtree, keyed by the name you gave it. Net-SNMP exposes both the output text and the command's exit code, so a script that exits non-zero on failure gives you a health signal as well as a value.

A couple of practical cautions with extend, since it's the one most people reach for. First, the script runs as the snmpd user and every time the OID is polled — so keep it fast and cheap, because a slow script blocks the agent and a poll every 30 seconds means the script runs every 30 seconds. Anything expensive is better run on a cron schedule that writes a file, with the extend script just cat-ing that file. Second, mind the security surface: you're letting a remote poller trigger local command execution, so lock down who can reach the agent, never pass unsanitised SNMP input into the command, and prefer a read-only community or SNMPv3 scoped to just the extend subtree. Treated with that care, extend is the fastest route from "a shell one-liner knows this" to "my NMS graphs it."

Using pass / pass_persist

Where extend runs a command and captures its output, pass hands an entire OID subtree to a script — your script becomes the agent for that branch, answering GET, GETNEXT and optionally SET for every OID under it:

pass 1.3.6.1.4.1.8072.9999 /usr/local/bin/my_subtree.pl

Now any query under 1.3.6.1.4.1.8072.9999 is passed to your script, which must implement the pass protocol (respond to -g/-n/-s arguments with the OID, type, and value). pass_persist is the same idea but keeps the script running between requests instead of spawning it each time — much faster for anything polled frequently. Use pass/pass_persist when you have a structured set of values to expose, not just a single script output.

AgentX subagents

For richer or higher-performance modules, AgentX (RFC 2741) lets a separate process — a subagent — register OIDs with the master snmpd over a local socket. It's the heavyweight option: you write a real subagent (in C, Python via a binding, etc.) rather than a shell script, but you get full control, persistence, and performance. This is how many vendor and application MIBs are implemented. The mechanism is covered in depth on AgentX architecture; reach for it when extend/pass aren't structured or fast enough.

Worked example

A script that prints a number:

#!/bin/bash
echo $(ls /var/spool/myqueue | wc -l)

The snmpd.conf line to expose it:

extend queuedepth /usr/local/bin/queue_depth.sh

After reloading snmpd, read it back:

snmpwalk -v2c -c <RO_string> localhost 1.3.6.1.4.1.8072.1.3.2
NET-SNMP-EXTEND-MIB::nsExtendOutputLine."queuedepth".1 = STRING: 42
NET-SNMP-EXTEND-MIB::nsExtendResult."queuedepth" = INTEGER: 0

The queue depth (42) is now a pollable OID, and nsExtendResult of 0 confirms the script exited cleanly. Point your NMS at that OID like any other. <RO_string> is a placeholder; keep live communities out of committed scripts.

snmpd.conf extend directive and the resulting snmpwalk output

Choosing your enterprise OID

Custom metrics must live under an OID space you're allowed to use — your enterprise (Private Enterprise Number) arc at 1.3.6.1.4.1.<PEN>. Net-SNMP's own PEN is 8072, which is why the extend output lands under 1.3.6.1.4.1.8072. For your own organisation's objects you'd register a PEN and use 1.3.6.1.4.1.<your-PEN> so your OIDs never collide with anyone else's. More on that: enterprise OIDs.

Frequently asked questions

How do I add a custom SNMP OID?

Use one of Net-SNMP's three mechanisms: extend to run a script and expose its output under the NET-SNMP-EXTEND-MIB, pass/pass_persist to hand a whole OID subtree to a script, or an AgentX subagent for a compiled/persistent module. For most needs, extend is the simplest — add one line to snmpd.conf and read the result.

What is snmpd extend?

extend is a snmpd.conf directive that runs a named command and publishes its stdout and exit code over SNMP under the NET-SNMP-EXTEND-MIB (1.3.6.1.4.1.8072.1.3.2). It's the standard way to expose a script's output — a queue depth, a health check, a custom count — as a pollable OID without writing a full subagent.

Where does extend output appear?

Under nsExtendOutputLine in the NET-SNMP-EXTEND-MIB at 1.3.6.1.4.1.8072.1.3.2, keyed by the name you gave the extend entry. The first line of the command's output is nsExtendOutputLine."name".1, and the command's exit code is available as nsExtendResult."name".

Which OID should I use for custom metrics?

Put them under your enterprise arc 1.3.6.1.4.1.<PEN>, using a Private Enterprise Number registered to your organisation so they never collide with standard or other-vendor objects. Net-SNMP's extend output uses Net-SNMP's own PEN (8072); for your own MIB objects, use your assigned PEN.

Key takeaways

  • Three ways to expose custom metrics: extend (script output), pass/pass_persist (own a subtree), AgentX (subagent).
  • extend output lands under NET-SNMP-EXTEND-MIB (1.3.6.1.4.1.8072.1.3.2) as nsExtendOutputLine.
  • nsExtendResult carries the script's exit code — a free health signal.
  • Use pass_persist over pass for frequently polled subtrees (keeps the script running).
  • Custom metrics belong under your enterprise OID 1.3.6.1.4.1.<PEN> — see enterprise OIDs.
  • Deeper: AgentX architecture; catalog: sensors/all.

Monitor it from outside the network

SNMP only tells you a box is healthy while something is still asking. ostr.io polls your endpoints externally and fires email + SMS alerts the moment a reading crosses your line — or the agent goes silent.