# libcoap: a CoAP implementation in C for devices that cannot afford much

> libcoap implements the Constrained Application Protocol, RFC 7252, in C for devices constrained in computing power, RF range, memory, bandwidth or packet size, with ports for Contiki-NG, ESP-IDF, lwIP, RIOT and Zephyr. It covers a wide band of CoAP RFCs and six TLS backends, and the last tagged release is three years old.

**obgm/libcoap** — A CoAP (RFC 7252) implementation in C

- Repository: https://github.com/obgm/libcoap
- Stars: 922 · Forks: 481
- Language: C
- License: NOASSERTION
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/obgm-libcoap

## A protocol library sized for the device it runs on

libcoap is a C implementation of a lightweight application protocol for devices that are constrained in their resources, such as computing power, RF range, memory, bandwidth or network packet sizes. That protocol is CoAP, standardized by the IETF as RFC 7252, with further reading at coap.space and a CoAP wiki.

The problem it solves is narrow and technical. CoAP is the request and response protocol designed for constrained networks, and an embedded device that has to speak it needs three things that are tedious to get right: a message parser that handles the binary option format, a transport that can run over UDP, and a security layer that does not assume a full TCP and TLS stack. libcoap provides the first two directly and the third through a set of pluggable TLS backends.

The package contents section states the scope precisely. It contains a protocol parser and basic networking functions for platforms with support for malloc and BSD-style sockets, and in addition there is support for Contiki-NG, Espressif/ESP-IDF, LwIP and RIOT-OS hosted environments.

That last sentence is the one to note. On a desktop, this is a C library you link against. On the platforms that motivated the protocol, it is a port with its own configuration header, and the repository carries coap_config.h.contiki, coap_config.h.riot, coap_config.h.windows and a zephyr/ directory alongside the general build system.

## The RFC list is the real feature list

The README enumerates the specifications the library implements, and the list is long enough to be the best summary of the project's capabilities.

Starting with RFC7252, the base protocol, it covers RFC7390 for group communication, RFC7641 for observing resources, RFC7959 for block-wise transfers, RFC7967 for the no server response option, RFC8132 for PATCH and FETCH methods, RFC8323 for CoAP over TCP, TLS and WebSockets, RFC8516 for the too many requests response code, RFC8613 for OSCORE object security, RFC8768 for the hop-limit option, RFC8974 for extended tokens and stateless clients, RFC9175 for Echo, Request-Tag and token processing, and RFC9177 for block-wise transfer options supporting robust transmission. There is also support for an Internet Draft on URI-Path abbreviation in CoAP.

Three of those entries change what an application can do, and they are worth separating from the rest.

RFC7641 observing resources is the subscription mechanism: a client registers interest in a resource and receives updates when it changes, rather than polling. RFC7959 and RFC9177 are block-wise transfers, which is how a payload larger than the frame size is split and reassembled, and RFC9177 adds robustness so a lost block is retransmitted rather than failing the whole transfer. RFC8613 is OSCORE, object security for constrained RESTful environments, which is layer security that does not rely on DTLS at all.

The pattern is that a device with a small radio buffer and an unreliable link needs reliability features at the protocol level, and these RFCs are where they are.

## Six TLS backends, each with its own capability matrix

There is DTLS support for a listed set of libraries, and the README annotates each one with the authentication modes and minimum version it supports.

OpenSSL is supported from version 1.1.0 with PKI, PSK and PKCS11. GnuTLS is supported from 3.3.0 with PKI, PSK, RPK from 3.6.6 and PKCS11. Mbed TLS is supported from 2.7.10 with PKI and PSK. wolfSSL is supported from 5.2.0 with PKI, PSK, RPK from 5.6.4 and DTLS 1.3 from 5.4.0. TinyDTLS offers PSK and RPK with DTLS only, and openHiTLS is supported from 0.4.0 with PKI and PSK.

Those annotations are the part that matters, because the choice is rarely free. A device with a hardware secure element wants PKCS11, which narrows the field to OpenSSL, GnuTLS or openHiTLS. A device with a provisioned shared secret wants PSK, which almost everything supports. A device with a certificate wants PKI and has to check that the backend version in the firmware is new enough, since the RPK and DTLS 1.3 entries are version gated.

The HOWTO files at the top of the tree show how seriously this is taken. There is HOWTO.dual.gnutls, HOWTO.dual.openssl and HOWTO.dual.softhsm2 for building against two TLS stacks at once, and HOWTO.pkcs11 for hardware token support.

Dual builds exist because a device fleet often spans generations: a hardware token driver that only exists for one platform, and a software fallback for the rest.

## Porting: Contiki, ESP-IDF, lwIP, RIOT, Zephyr and Windows

The platform support is what turns a protocol library into something an embedded team can actually ship.

Alongside the hosted build for platforms with malloc and BSD-style sockets, the README names Contiki-NG, Espressif/ESP-IDF, LwIP and RIOT-OS as hosted environments with support. The tree contains dedicated directories for contiki/, riot/, lwip/ and zephyr/ under examples/, and configuration headers named after Contiki, RIOT and Windows, plus a zephyr/ directory at the top level.

The examples directory doubles as the test surface. It contains a CoAP client, a CoAP Resource Directory server and a CoAP server, plus an oscore-interop-server.c. Alongside them sit shell scripts for conformance and interoperability: etsi_testcases.sh, etsi_coaptest.sh, oscore_testcases.sh, tls_backend_testcases.sh and a share.libcoap.examples.Makefile that links the shared test code.

That naming is worth pausing on. The ETSI test cases are the industry conformance suite for CoAP, so the project can check itself against the standard rather than only against itself. The OSCORE and TLS backend test scripts are narrower checks on the two areas where an implementation most easily diverges from the specification.

For an evaluator, this is the strongest signal in the repository. A CoAP library that passes the ETSI test cases and is fuzzed by OSS-Fuzz is a library you can reason about.

## Building with autotools, CMake and a Docker build environment

Build information lives outside the README. Further information can be found at libcoap.net/install.html and in the BUILDING file at the root of the repository.

The tree shows a dual build system. There is configure.ac with m4/ macros and autogen.sh, alongside Makefile.am, Makefile.libcoap and CMakeLists.txt with a cmake/ directory, CMakePresets.json, and cmake-format.yaml. The pkg-config file libcoap-3.pc.in and the symbol files libcoap-3.sym and libcoap-3.map show that the library is versioned and exports a controlled symbol set, which is what you want from something that ends up in firmware images.

The Dockerfile in the repository shows the containerised route, and it is minimal because it is a build environment image rather than a runtime image:

```dockerfile
FROM obgm/libcoap:build-env

ENV libcoap_dir=/libcoap
ADD . $libcoap_dir
WORKDIR $libcoap_dir

RUN ./autogen.sh --clean && ./autogen.sh
```

The base image is a prebuilt build environment, and the container simply runs the autotools bootstrap twice, once clean and once for real. That sequence matters: --clean removes generated state so a stale configure script does not survive from a previous run, which is the usual cause of a mysterious build failure after a toolchain upgrade.

The continuous integration signals in the README are equally relevant to an embedded project. There is a build status badge for the develop branch, a Coverity static analysis badge, an OSS-Fuzz fuzzing status badge, a CIFuzz status badge, and a pre-commit configuration. Fuzzing a binary protocol parser that parses input from the network is not optional, and the fact that this project runs under OSS-Fuzz says it treats the parser as hostile input by default.

## Licence terms and a release tag that is three years old

The licence section says the library is published as open-source software without any warranty of any kind, that use is permitted under the terms of the simplified BSD license, and that it includes public domain software. It adds that libcoap binaries may also include open-source software with their respective licensing terms, and points to the LICENSE file for further details.

The licence field on the repository, meanwhile, reports a custom licence that GitHub cannot classify, and the tree carries both a LICENSE and a COPYING file. Read the LICENSE file directly rather than trusting the badge, since the package also includes public domain code and third-party components whose terms are separate.

The copyright line credits Olaf Bergmann and others from 2010 to 2026, which is a long run for a single library.

The more important fact for an adopter is the release record. Only one release is listed: v4.3.2-rc1, a tag release candidate for version 4.3.2, from 2023-07-22. The repository is not archived and the last push was on 2026-10-17, and the default branch is develop rather than a release branch.

The GitHub Releases page and Git tags are separate: a release candidate shown on the former does not establish the date of the newest tag. Check the tags and upstream release guidance for the version you plan to deploy, and record the selected version or commit when building firmware.

## Conclusion

libcoap suits a firmware team building a constrained device that has to speak CoAP to a real server, and who want the protocol details handled by a library with fuzzing, static analysis and a conformance test suite rather than by hand. It does not suit a team that needs a tagged release to pin against, because the only tag listed is a release candidate from 2023 while the tree itself is still being worked on. Before adopting, read the LICENSE file at the root of the repository rather than the badge, build the library against the TLS backend your device can actually use, and check libcoap-minimal for runnable examples before writing your own first client.

## FAQ

### What is libcoap and which specification does it implement?

libcoap is a C implementation of the Constrained Application Protocol, CoAP, standardized by the IETF as RFC 7252, intended for devices constrained in computing power, RF range, memory, bandwidth or packet size. The package contains a protocol parser and basic networking functions for platforms with malloc and BSD-style sockets.

### Which CoAP RFCs does libcoap support?

The README lists RFC7252, RFC7390 group communication, RFC7641 observing resources, RFC7959 block-wise transfers, RFC7967 no server response, RFC8132 PATCH and FETCH, RFC8323 CoAP over TCP, TLS and WebSockets, RFC8516 too many requests, RFC8613 OSCORE, RFC8768 hop-limit, RFC8974 extended tokens, RFC9175 Echo, Request-Tag and token processing, and RFC9177 robust block-wise transfer.

### Which TLS libraries can libcoap use?

OpenSSL from 1.1.0, GnuTLS from 3.3.0, Mbed TLS from 2.7.10, wolfSSL from 5.2.0, TinyDTLS with DTLS only, and openHiTLS from 0.4.0. The README annotates each with the authentication modes available, including PKI, PSK, PKCS11 and RPK where the backend version supports them.

### Which embedded platforms does libcoap support?

The README states that in addition to the hosted build there is support for Contiki-NG, Espressif/ESP-IDF, LwIP and RIOT-OS hosted environments. The repository carries examples for contiki, riot, lwip and zephyr, plus configuration headers for Contiki, RIOT and Windows.

### When was the last libcoap release?

The only release listed is v4.3.2-rc1, a release candidate for version 4.3.2, published on 2023-07-22. The repository is not archived, the default branch is develop, and the last push was on 2026-10-17.

## Sources

- [Issues](https://github.com/obgm/libcoap/issues)
- [obgm/libcoap on GitHub](https://github.com/obgm/libcoap)
- [README](https://github.com/obgm/libcoap/blob/develop/README.md)
- [Releases](https://github.com/obgm/libcoap/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/obgm-libcoap
