gosnmp, an SNMP client library written entirely in Go
An SNMP library written in Go
At a glance
- What is it?
- gosnmp implements Get, GetNext, GetBulk, Walk, Set and traps over SNMPv1, v2c and v3 with IPv4 and IPv6, with no MIB parser and no dependency on net-snmp. It grew out of a fork, diverged from it, and now sits with community ownership.
- Who is it for?
- gosnmp fits a Go team that has to talk to network devices and wants the SNMP handling in the same language and the same binary as the rest of the service, and it fits a team that receives traps and needs to act as a small NMS. It does not fit a developer who wants human readable OID names, since the library has no MIB parser and the project states it has no plans to write one, and it does not fit a project that needs an agent, since this is a client.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The operation set, and what is deliberately missing
gosnmp is an SNMP client library fully written in Go, and the operation list covers what a monitoring agent needs. There is Get for single or multiple OIDs, GetNext, and GetBulk, which the documentation marks as SNMPv2c and SNMPv3 only. On top of the primitives sit the walkers. Walk retrieves a subtree of values using GETNEXT, BulkWalk does the same with GETBULK, again only on v2c and v3, and BulkWalkAll returns a filled array of all values instead of streaming them through a callback, which is the variant you want when the tree is small and you would rather have the whole thing in memory. Set supports integers and octet strings. Traps work in both directions, SendTrap to send and Listen to act as an NMS and receive them. What is not there is a MIB parser, and the author is explicit that there are no plans to write one, pointing instead at another project. The practical consequence is that every OID in your code is a raw numeric string, and someone on the team has to own the mapping from that string to a human readable meaning.
A default client, a connect call and a typed result
The usage example is short enough to read in one go, and it shows the shape of the whole API. A default client is a pointer to a GoSNMP struct that carries sensible defaults, port 161 and community public among them, and you set the target on it before connecting.
g.Default.Target = "192.168.1.10"
err := g.Default.Connect()
if err != nil {
log.Fatalf("Connect() err: %v", err)
}
defer g.Default.Conn.Close()
oids := []string{"1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.7.0"}
result, err2 := g.Default.Get(oids) // Get() accepts up to g.MAX_OIDSThe result holds a list of variables, and each variable has a Name, a Type and a Value that is an interface, so the caller switches on the type to interpret it. The library ships two helpers to make that less painful. ToBigInt treats a returned value as a big integer, which covers most numeric OIDs, and Partition divides a large slice of OIDs into chunks, which is what you need when the OID count exceeds the maximum a single Get accepts. The examples directory makes the variations explicit, with one example per shape: a plain example, a second that uses a custom GoSNMP struct instead of the default, a walk example using BulkWalk, a third showing SNMPv3, and a trap server example that writes an SNMP v2c trap server.
The fork, the rewrite and the API break
The history explains the API. gosnmp was started by Andreas Louca and then completely rewritten by Sonia Hamilton between 2012 and 2020, and ownership has since been transferred to the community at the gosnmp/gosnmp repository. The rewrite means the current library has completely diverged from alouca/gosnmp, and the documentation lists the places your code will need to change. The Get function has a different method signature, the NewGoSNMP function has been removed so you use Connect instead, with the GoSNMP struct and the provided gosnmp.Default to build on, and the library no longer relies on alouca/gologger. That last change is the friendliest part of the migration, because logging is now an interface you can satisfy with your own logger, and the interface is two methods, Print and Printf.
type LoggerInterface interface {
Print(v ...interface{})
Printf(format string, v ...interface{})
}If your logger does not conform, debugging output is simply disabled. To get logging you call gosnmp.NewLogger and pass a pointer to your interface, either on the default client or on a struct you built yourself. There is also a build tag, gosnmp_nodebug, that removes the logging code entirely, which the documentation describes as a small performance improvement.
go build -tags gosnmp_nodebugWhere SNMPv3 lives in the tree
The v3 implementation is spread across dedicated files, and the file names describe the parts of the standard that are hard. v3.go holds the main v3 message handling, v3_map.go the mapping tables, and v3_usm.go the User Security Model. The test files are more revealing than the implementation, because they name the problem areas. There is a v3_discovery_test.go for engine discovery, which is the step where a client learns the authoritative engine identifier of an agent, v3_credentials_test.go for the authentication and privacy credentials, and a pair of password cache tests, v3_usm_pwdcache_test.go and v3_usm_nopwdcache_test.go, which check behaviour with and without a cache of the localised keys. The stringer generated files, asn1ber_string.go, pdutype_string.go, snmperror_string.go and the four v3 enumerations, show that the library relies on Go's stringer tool to give the ASN.1 BER types, the PDU types and the v3 protocol enumerations readable names, which is what makes the error messages usable when a device returns something unexpected.
The BER type list is the compatibility contract
The README publishes the full list of implemented BER types, and for a client library this list is the real interface with the devices you will meet. Implemented are the standard ones, 0x00 UnknownType, 0x01 Boolean, 0x02 Integer, 0x03 BitString, 0x04 OctetString, 0x05 Null, 0x06 ObjectIdentifier and 0x07 ObjectDescription. Then come the application types that carry most of the interesting data, 0x40 IPAddress for both IPv4 and IPv6, 0x41 Counter32, 0x42 Gauge32, 0x43 TimeTicks, 0x44 Opaque for float and double, 0x45 NsapAddress, 0x46 Counter64, 0x47 Uinteger32, and the opaque float and double variants at 0x78 and 0x79. The end of MIB markers are there too, 0x80 NoSuchObject, 0x81 NoSuchInstance and 0x82 EndOfMibView, which is what a walker uses to know it has reached the end of a subtree. If a device returns a type that is not on this list, the failure surfaces as a decode error rather than as a configuration mistake, which is why the project asks for bug reports to come with packet captures and two or three examples of the missing type.
Testing against a real net-snmp inside a container
The Dockerfile shows how the project tests itself, and the answer is a real agent rather than a mock. The image is golang:1.22-alpine with net-snmp and net-snmp-tools installed, along with openssl-dev for the v3 privacy protocols, python3, gcc, make and bash. A dedicated user is created with uid 1001, and the permissions on /etc/snmp and /var/lib/net-snmp are opened up so that the test agent can run as that user. The environment variables define the topology the tests expect, with GOSNMP_TARGET and GOSNMP_TARGET_IPV4 pointing at 127.0.0.1, GOSNMP_TARGET_IPV6 at ::1, port 1024 for the IPv4 and IPv6 targets, and GOSNMP_SNMPD set to true to start the agent. The entrypoint is build_tests.sh, with local_tests.sh and snmp_users.sh alongside it for running subsets and provisioning test users. The Makefile is small, the test target runs go test ./... and the lint target is really a licence check, which walks every Go file and fails if the first three lines do not contain a copyright notice for the GoSNMP Authors or a generated marker.
Community ownership, frequent releases, a licence to check
The project is not archived and the last push was on 2026-10-01, and the release tags are frequent, with v1.45.0 on 2026-09-19, v1.44.0 on 2026-07-16 and v1.43.2 on 2026-01-12, so a consumer can expect a release every few months rather than a long freeze. Support is handled in the snmp channel of the Gophers Slack, and contributions are actively solicited, with packet captures called out as the most valuable contribution. The repository carries a CHANGELOG.md, a RELEASE.md that documents the release process, an AUTHORS.md, and a .golangci.yml for the linter configuration, along with a mocks/ directory and a netsnmp/ directory for comparing behaviour against the reference implementation. The licence is the item to check before you ship. GitHub could not classify it as a standard licence, which means the terms live in a custom LICENSE file rather than in a named grant, and the module manifest does not carry a licence identifier in the go.mod. A company embedding this in a commercial product needs to read that file rather than assume the usual Go library defaults, and nothing here is legal advice.
Editorial conclusion
gosnmp fits a Go team that has to talk to network devices and wants the SNMP handling in the same language and the same binary as the rest of the service, and it fits a team that receives traps and needs to act as a small NMS. It does not fit a developer who wants human readable OID names, since the library has no MIB parser and the project states it has no plans to write one, and it does not fit a project that needs an agent, since this is a client. Verify three things first: that your devices speak the version and the authentication scheme you configure, that the version you import is the community owned fork rather than the older alouca/gosnmp, whose API differs in the Get signature and in how a client is created, and that the BER types your devices return are in the implemented list, since an unimplemented type shows up as a decode problem rather than as a configuration mistake.
Frequently asked questions
What operations does gosnmp support?
It provides Get for single or multiple OIDs, GetNext, GetBulk on SNMPv2c and v3, Walk, BulkWalk and BulkWalkAll for subtrees, Set for integers and octet strings, SendTrap to send traps and Listen to receive them as an NMS. It supports IPv4 and IPv6 with SNMPv1, SNMPv2c and SNMPv3.
How do I install gosnmp?
The documented install is go get github.com/gosnmp/gosnmp. The module is github.com/gosnmp/gosnmp and its go.mod declares go 1.24.0, with golang/mock and stretchr/testify as the only direct dependencies.
Does gosnmp include a MIB parser?
No. The README states there are no plans to write a MIB parser and points readers at the gosmi project instead, so OIDs in your code are raw numeric strings and the mapping to readable names has to live somewhere else.
How do I enable logging in gosnmp?
Implement the LoggerInterface, which requires Print and Printf, then call gosnmp.NewLogger with a pointer to your logger and assign it to the Logger field of the GoSNMP struct or of gosnmp.Default. Building with the gosnmp_nodebug tag removes the logging code entirely for a small performance gain.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/gosnmp-gosnmp)Was this useful?