diff --git a/sys/net/application_layer/nanocoap/nanocoap.c b/sys/net/application_layer/nanocoap/nanocoap.c
index 455ebfe7e28b91ba55908de96b8f97e5d49ee55c..5b5056e649ca330ccaa638ad8229d109f15ad440 100644
--- a/sys/net/application_layer/nanocoap/nanocoap.c
+++ b/sys/net/application_layer/nanocoap/nanocoap.c
@@ -499,7 +499,35 @@ static size_t _encode_uint(uint32_t *val)
     return size;
 }
 
-static unsigned _put_delta_optlen(uint8_t *buf, unsigned offset, unsigned shift, unsigned val)
+/*
+ * Writes CoAP Option header. Expected to be called twice to write an option:
+ *
+ * 1. write delta, using offset 1, shift 4
+ * 2. write length, using offset n, shift 0, where n is the return value from
+ *    the first invocation of this function
+ *
+ *     0   1   2   3   4   5   6   7
+ *   +---------------+---------------+
+ *   |  Option Delta | Option Length |   1 byte
+ *   +---------------+---------------+
+ *   /         Option Delta          /   0-2 bytes
+ *   \          (extended)           \
+ *   +-------------------------------+
+ *   /         Option Length         /   0-2 bytes
+ *   \          (extended)           \
+ *   +-------------------------------+
+ *
+ *   From RFC 7252, Figure 8
+ *
+ * param[out] buf       addr of byte 0 of header
+ * param[in]  offset    offset from buf to write any extended header
+ * param[in]  shift     bit shift for byte 0 value
+ * param[in]  value     delta/length value to write to header
+ *
+ * return     offset from byte 0 of next byte to write
+ */
+static unsigned _put_delta_optlen(uint8_t *buf, unsigned offset, unsigned shift,
+                                  unsigned val)
 {
     if (val < 13) {
         *buf |= (val << shift);
@@ -689,8 +717,14 @@ static ssize_t _add_opt_pkt(coap_pkt_t *pkt, uint16_t optnum, uint8_t *val,
             ? pkt->options[pkt->options_len - 1].opt_num : 0;
     assert(optnum >= lastonum);
 
-    size_t optlen = coap_put_option(pkt->payload, lastonum, optnum, val, val_len);
-    assert(pkt->payload_len > optlen);
+    /* calculate option length */
+    uint8_t dummy[3];
+    size_t optlen = _put_delta_optlen(dummy, 1, 4, optnum - lastonum);
+    optlen += _put_delta_optlen(dummy, 0, 0, val_len);
+    optlen += val_len;
+    assert(pkt->payload_len >= optlen);
+
+    coap_put_option(pkt->payload, lastonum, optnum, val, val_len);
 
     pkt->options[pkt->options_len].opt_num = optnum;
     pkt->options[pkt->options_len].offset = pkt->payload - (uint8_t *)pkt->hdr;
diff --git a/tests/unittests/tests-nanocoap/tests-nanocoap.c b/tests/unittests/tests-nanocoap/tests-nanocoap.c
index 38185b2bbd5ca0a380ff5617bec549762cb21f6c..b742fadd97da2742542ecc5af25a9ac8343cd2e7 100644
--- a/tests/unittests/tests-nanocoap/tests-nanocoap.c
+++ b/tests/unittests/tests-nanocoap/tests-nanocoap.c
@@ -330,6 +330,29 @@ static void test_nanocoap__get_multi_query(void)
     TEST_ASSERT_EQUAL_STRING((char *)qs, &query[1]);
 }
 
+/*
+ * Builds on get_req test, to test building a PDU that completely fills the
+ * buffer.
+ */
+static void test_nanocoap__option_add_buffer_max(void)
+{
+    uint8_t buf[70];    /* header 4, token 2, path 64 */
+    coap_pkt_t pkt;
+    uint16_t msgid = 0xABCD;
+    uint8_t token[2] = {0xDA, 0xEC};
+    char path[] = "/23456789012345678901234567890123456789012345678901234567890123";
+
+    size_t uri_opt_len = 64;    /* option hdr 2, option value 62 */
+
+    size_t len = coap_build_hdr((coap_hdr_t *)&buf[0], COAP_TYPE_NON,
+                                &token[0], 2, COAP_METHOD_GET, msgid);
+
+    coap_pkt_init(&pkt, &buf[0], sizeof(buf), len);
+
+    len = coap_opt_add_string(&pkt, COAP_OPT_URI_PATH, &path[0], '/');
+    TEST_ASSERT_EQUAL_INT(uri_opt_len, len);
+}
+
 /*
  * Helper for server_get tests below.
  * GET Request for nanocoap server example /riot/value resource.
@@ -531,6 +554,7 @@ Test *tests_nanocoap_tests(void)
         new_TestFixture(test_nanocoap__get_path_too_long),
         new_TestFixture(test_nanocoap__get_query),
         new_TestFixture(test_nanocoap__get_multi_query),
+        new_TestFixture(test_nanocoap__option_add_buffer_max),
         new_TestFixture(test_nanocoap__server_get_req),
         new_TestFixture(test_nanocoap__server_reply_simple),
         new_TestFixture(test_nanocoap__server_get_req_con),