Self-hosted service
fxamacker/cbor avatar
fxamacker/cbor

fxamacker/cbor is a CBOR codec that refuses to allocate its way out of bad input

CBOR codec (RFC 8949, RFC 8742) with CBOR tags, Go struct tag options (toarray, keyasint, omitempty, omitzero), float64/32/16, big.Int, and fuzz tested.

1,096 stars90 forksGoMIT

At a glance

What is it?
fxamacker/cbor is a Go implementation of CBOR with configurable decoder limits, duplicate map key detection and a fuzzing programme, and it is also usable as a JSON transcoding front end. Its two selling points are that it rejects malformed data fast and that its API mirrors encoding/json closely enough to be a drop-in for most code.
Who is it for?
Adopt fxamacker/cbor if you need CBOR in Go and you care about what happens when a peer sends you garbage, because the decoder is built around configurable limits and a fuzzing programme rather than around the happy path. Do not adopt it if you need CBOR sequences or the extended diagnostic notation without reading the version notes, because those are newer additions and the API surface is larger than a plain codec.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
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

CBOR as a standards-track alternative to JSON

The library encodes and decodes CBOR and CBOR Sequences. CBOR is described as a trusted alternative to JSON, MessagePack and Protocol Buffers, defined by IETF as an Internet Standard, STD 94, which is RFC 8949, and designed to be relevant for decades. The case for the format is that it is binary and self-describing, and the case for this particular implementation is that it is in full conformance with that standard. It also supports CBOR Sequences under RFC 8742, which is the framing format for a stream of CBOR items, and Extended Diagnostic Notation from Appendix G of RFC 8610, which is the human-readable form of the same data. The README also notes the newer `UnmarshalFirst` and `DiagnoseFirst` functions for decoding sequences, and `MarshalToBuffer` and `UserBufferEncMode` for writing into a buffer you supply.

The decoder is built to fail, not to allocate

The security section is the most substantive part of the documentation, and it is specific about the threat. The decoder has configurable limits that defend against malicious CBOR data, and duplicate map key detection is supported, which matters because a duplicate key is a classic way to make two implementations disagree about what a document says. The library is also contrasted with `encoding/gob`, which is not designed to be hardened against adversarial inputs, and the README shows gob running out of memory while decoding a small amount of bad data, a failure mode that the configurable limits here are meant to prevent. The default limits are described as allowing very fast and memory efficient rejection of malformed CBOR data, and the slower settings are opt-in. The codec also passed multiple confidential security assessments in 2022, with no vulnerabilities found in the subset of the codec covered by a nonconfidential assessment.

The rejection benchmark is the argument in numbers

The README benchmarks decoding ten bytes of malicious CBOR data into a Go byte slice, and the gap is large enough to be the reason to pick one library over another. fxamacker/cbor 2.7.0 is listed at 47 nanoseconds per operation with 32 bytes per operation and 2 allocations, while ugorji/go 1.2.12 is listed at 5,878,187 nanoseconds per operation with 67,111,556 bytes per operation and 13 allocations. The older comparison against ugorji 1.1.0 to 1.2.6 records a runtime out of memory, and the note about faster hardware with overclocked DDR4 or DDR5 says the difference can shrink on better machines, which is an honest caveat rather than a hedge. The benchmark itself is specified down to the input bytes, the Go version, the processor, and the go test flags, so you can reproduce it rather than take it on faith.

The API is mostly encoding/json with CBOR options

The stated design goal is that the API is mostly the same as `encoding/json`, plus interfaces that simplify concurrency and CBOR options, and the design is described as balancing trade-offs between security, speed, concurrency, encoded data size and usability. The concurrency part is the one worth spelling out. Encoding and decoding modes can be created at startup and then reused by any goroutines, rather than constructing an encoder per call, which is the pattern that makes a codec expensive to use in a concurrent service. There are also presets for common needs, including Core Deterministic Encoding, Preferred Serialization and CTAP2 Canonical CBOR. The extensibility story is that there are CBOR extension points such as tags, and interfaces that let you build custom encoding and decoding without modifying the library.

Struct tags that shrink the payload

The data size section covers the options that reduce what goes on the wire. The struct tag options are `toarray`, which encodes a struct as an array rather than a map, `keyasint`, which uses integer keys, `omitempty` and `omitzero`, and a field tag of `-`. Encoding can also shrink a float64 down to a float32 or a float16 when the value fits, which the repository description lists alongside float64, float32 and float16 support. Big integers are supported through Go's `big.Int`. Together these are the options that make CBOR a practical choice for constrained or high-volume protocols rather than only an academic one, and they are opt-in, so the default encoding stays conventional.

Fuzzing and the shape of the codebase

The repository badges show a continuous integration workflow, a coverage workflow, a CodeQL analysis workflow and a fuzzing badge, and the description lists the library as fuzz tested. The top level of the repository is flat and tells you how the code is organised: `encode.go` and `decode.go` for the two directions, `encode_map.go` and `decode_map_utils.go` for the map handling, `structfields.go` and `tag.go` for the reflection over struct tags, `simplevalue.go` for the fast paths, `bytestring.go` for a string type that avoids a copy, `cache.go` for the reflection cache, `valid.go` for validation, `diagnose.go` for the diagnostic notation, and `stream.go` for the sequence framing. There is a `bench_test.go` at the root, which is where the benchmarks in the README come from, and files such as `json_test.go` and `example_transcoding_test.go` that show the library being used as a transcoding layer between JSON and CBOR.

The module is small, and one tag was pulled

The go.mod is unusually short. The module path is `github.com/fxamacker/cbor/v2`, it requires Go 1.24, and the only dependency is `github.com/x448/float16` at v0.8.4, which is there for the float16 support. There is also a `retract` directive, and the comment is worth reading because it is a small maintenance lesson: v2.9.5 is retracted because it was tagged from the wrong branch, and the instruction is to use v2.9.6 or later. The current release is v2.9.6 from 2026-10-06, with v2.9.5 and v2.9.4 in the days before it, and the last push to the master branch was on 2026-10-15. The library is used in projects by Arm, EdgeX Foundry, IBM, Kubernetes, Let's Encrypt, Microsoft, Red Hat and Tailscale among others, which is the best evidence available about its staying power.

Editorial conclusion

Adopt fxamacker/cbor if you need CBOR in Go and you care about what happens when a peer sends you garbage, because the decoder is built around configurable limits and a fuzzing programme rather than around the happy path. Do not adopt it if you need CBOR sequences or the extended diagnostic notation without reading the version notes, because those are newer additions and the API surface is larger than a plain codec. Verify first which Go version you are on against the module requirement, that the limits you set are appropriate for your message sizes, and which encoding preset you need, since Core Deterministic Encoding and the CTAP2 canonical form are not the same thing.

Frequently asked questions

What is fxamacker/cbor?

It is a Go library for encoding and decoding CBOR and CBOR Sequences, in full conformance with IETF STD 94, RFC 8949, with support for CBOR tags, Core Deterministic Encoding and duplicate map key detection. The API is mostly the same as encoding/json.

How does fxamacker/cbor protect against malicious input?

The decoder has configurable limits that defend against malicious CBOR data, and the default limits allow fast and memory efficient rejection of malformed input. Duplicate map key detection is supported, and the codec passed multiple confidential security assessments in 2022.

Which struct tag options does fxamacker/cbor support?

The options are toarray, keyasint, omitempty and omitzero, plus a field tag of - to skip a field. Encoding can also shrink a float64 down to float32 or float16 when the value fits.

How do I encode CBOR deterministically with fxamacker/cbor?

The library provides presets, among them Core Deterministic Encoding, Preferred Serialization and CTAP2 Canonical CBOR. The encoders and decoders can also be created once at startup and reused across goroutines, which is how the API is meant to be used in a concurrent service.

What licence is fxamacker/cbor released under?

The MIT licence, with the licence file in the repository root. The current release is v2.9.6 from 2026-10-06, and v2.9.5 was retracted because it was tagged from the wrong branch, with v2.9.6 or later recommended.

Official sources

  1. fxamacker/cbor on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/fxamacker-cbor.svg)](https://hysenlabs.com/projects/fxamacker-cbor)

Was this useful?