Description of the problem

You called serializeJson() or serializeJsonPretty() to generate a JSON document, but the result is incomplete.

For example, you wanted to write {"values":[0,1]}, but instead you got {"value":[]} or even {}. Or maybe you wanted to write {"hello":"world"}, but got {"hello":null}.

That’s because the JsonDocument is too small to store the complete tree.

How to solve it?

Increase the capacity of the JsonDocument:

  • add JSON_OBJECT_SIZE(n) for each object of size n,
  • add JSON_ARRAY_SIZE(n) for each object of size n,
  • add n+1 for each string of n characters.

You only need to include strings of type char*, String, and Flash strings because ArduinoJson copies them in the JsonDocument. You don’t need to count const char* and strings literals because ArduinoJson only stores a pointer.

Use the ArduinoJson Assistant to compute the right capacity for your project.

What happens if the capacity is too large?

On the one hand, the JsonDocument must be large enough to store your data; but on the other hand, it must be small enough to fit in the RAM of the microcontroller.

StaticJsonDocument

When a StaticJsonDocument is too large, it causes a stack overflow. Your program enters in the dark realm of “undefined behavior”: the program may run fine for a while and suddenly fail for inexplicable reasons. So be reasonable with the size of a StaticJsonDocument.

Some platforms limit the size of the stack (e.g., 4KB on the ESP8266), so consider switching to a DynamicJsonDocument that lives in the heap.

DynamicJsonDocument

DynamicJsonDocument calls malloc() in its constructor to allocate the memory pool. If this allocation fails, the DynamicJsonDocument has no memory pool and cannot store anything except the root value.

In other words, if you try to create a very large memory pool, you may end up without any memory pool at all!

In this situation, JsonDocument::capacity() returns 0, and serializeJson() outputs a empty object ({}), a empty array ([]) or null.

What if my microcontroller is too small?

Three solutions:

  1. Deserialize the input in smaller chunks, as shown in Mastering ArduinoJson
  2. Reduce memory usage
  3. Buy a larger microcontroller