diff --git a/lib/ngtcp2_pkt.c b/lib/ngtcp2_pkt.c
index 0e8d774709ca29196f6cd59fe2d3bc0c77343181..ad69c01a962e860bb7a938a04092e6a388c711e6 100644
--- a/lib/ngtcp2_pkt.c
+++ b/lib/ngtcp2_pkt.c
@@ -1997,15 +1997,27 @@ size_t ngtcp2_pkt_stream_max_datalen(uint64_t stream_id, uint64_t offset,
   size_t n = 1 /* type */ + ngtcp2_put_varint_len(stream_id) +
              (offset ? ngtcp2_put_varint_len(offset) : 0);
 
-  if (left < n) {
+  if (left <= n) {
     return (size_t)-1;
   }
 
-  n += ngtcp2_put_varint_len(ngtcp2_min(len, left - n));
+  left -= n;
 
-  if (left < n) {
-    return (size_t)-1;
+  if (left > 8 + 1073741823 && len > 1073741823) {
+    len = ngtcp2_min(len, 4611686018427387903lu);
+    return ngtcp2_min(len, left - 8);
+  }
+
+  if (left > 4 + 16383 && len > 16383) {
+    len = ngtcp2_min(len, 1073741823);
+    return ngtcp2_min(len, left - 4);
+  }
+
+  if (left > 2 + 63 && len > 63) {
+    len = ngtcp2_min(len, 16383);
+    return ngtcp2_min(len, left - 2);
   }
 
-  return ngtcp2_min(len, left - n);
+  len = ngtcp2_min(len, 63);
+  return ngtcp2_min(len, left - 1);
 }
diff --git a/tests/main.c b/tests/main.c
index 29398e26875572af297e758a00a253ea4d59003f..4fdfb00771ff18651a7d27c6412ce2ef47ad4dd1 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -124,6 +124,8 @@ int main() {
       !CU_add_test(pSuite, "pkt_write_retry", test_ngtcp2_pkt_write_retry) ||
       !CU_add_test(pSuite, "pkt_write_version_negotiation",
                    test_ngtcp2_pkt_write_version_negotiation) ||
+      !CU_add_test(pSuite, "pkt_stream_max_datalen",
+                   test_ngtcp2_pkt_stream_max_datalen) ||
       !CU_add_test(pSuite, "get_varint", test_ngtcp2_get_varint) ||
       !CU_add_test(pSuite, "get_varint_len", test_ngtcp2_get_varint_len) ||
       !CU_add_test(pSuite, "put_varint_len", test_ngtcp2_put_varint_len) ||
diff --git a/tests/ngtcp2_pkt_test.c b/tests/ngtcp2_pkt_test.c
index 51b3000ba31153f7eb9b3aac34ebd9fabb73535c..00818c28167d5a9f7992acfe04016a20904decea 100644
--- a/tests/ngtcp2_pkt_test.c
+++ b/tests/ngtcp2_pkt_test.c
@@ -1158,3 +1158,67 @@ void test_ngtcp2_pkt_write_version_negotiation(void) {
     CU_ASSERT(sv[i] == ngtcp2_get_uint32(p));
   }
 }
+
+void test_ngtcp2_pkt_stream_max_datalen(void) {
+  size_t len;
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 0, 2);
+
+  CU_ASSERT((size_t)-1 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 0, 3);
+
+  CU_ASSERT(0 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 1, 3);
+
+  CU_ASSERT(0 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 1, 4);
+
+  CU_ASSERT(1 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 1, 1, 4);
+
+  CU_ASSERT(0 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 63, 66);
+
+  CU_ASSERT(63 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 63, 65);
+
+  CU_ASSERT(62 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 1396, 1400);
+
+  CU_ASSERT(1396 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 1396, 1399);
+
+  CU_ASSERT(1395 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 1396, 9);
+
+  CU_ASSERT(6 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 16385, 16391);
+
+  CU_ASSERT(16385 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 16385, 16390);
+
+  CU_ASSERT(16384 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 1073741824, 1073741834);
+
+  CU_ASSERT(1073741824 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 1073741824, 1073741833);
+
+  CU_ASSERT(1073741823 == len);
+
+  len = ngtcp2_pkt_stream_max_datalen(63, 0, 16383, 16387);
+
+  CU_ASSERT(16383 == len);
+}
diff --git a/tests/ngtcp2_pkt_test.h b/tests/ngtcp2_pkt_test.h
index 23223fc099766b3cfef395e31d83875b1faa7303..34b9b3720eca102e2ae72346dd017b5c717b2b28 100644
--- a/tests/ngtcp2_pkt_test.h
+++ b/tests/ngtcp2_pkt_test.h
@@ -58,5 +58,6 @@ void test_ngtcp2_pkt_validate_ack(void);
 void test_ngtcp2_pkt_write_stateless_reset(void);
 void test_ngtcp2_pkt_write_retry(void);
 void test_ngtcp2_pkt_write_version_negotiation(void);
+void test_ngtcp2_pkt_stream_max_datalen(void);
 
 #endif /* NGTCP2_PKT_TEST_H */