Skip to content

Websocket multipart message does not work as expected #382

Description

@LSC-Labs

Platform

ESP8266

IDE / Tooling

PlatformIO

What happened?

I tried to send from the browser a json file (size about 1k) via web socket to the module.
I installed a new environment to avoid side effects and I used the code from the exsample folder: "WebSocket.ino"

The code is working with single frames and works as expected...
Then I inserted the code from https://github.com/ESP32Async/ESPAsyncWebServer/wiki#async-websocket-event to get also the
multipart message to receive the large messages.

  • The first message is received as expected... but with final set to true (!)
  • The second message will also be received.. also with final set to true and index set to 0, the data pointer contains garbage
    Output is (i inserted framelen with the parameter len to visualize it):
Connected clients: 1 / 1 total
index: 0, len: 1447, final: 1, opcode: 1, framelen: 528
ws[/ws][4] frame[0] text[0 - 4]: ws[/ws][5] text-message start
ws[/ws][5] frame[0] start[1447]
{     "logToSerial": true,     "traceMode": false,     "devicename": "LSC-device",     "devicepwd": "admin-geheim",     "autorestart": "86400",          "wifi": {         "ap_channel": 3,         "ap_hide": false,         "bssid": "aa:bb:33:22:11:fe",         "ap_ssid": "LSC-8eaa2c44",         "ap_mode": "0",         "dhcp": true,         "fallback": false,         "ssid": "WiFiOnICE",         "wifi_pwd": "JoJoBaOel",         "hostname": "LSC-Device"        },     "dewswitch": {         "dewdelta": 5.2,         "hysteresis
index: 0, len: 1447, final: 1, opcode: 1, framelen: 532
ws[/ws][5] frame[0] text[0 - 528]: ws[/ws][5] text-message start
ws[/ws][5] frame[0] start[1447]



index: 0, len: 1447, final: 1, opcode: 1, framelen: 379
ws[/ws][5] frame[0] text[0 - 532]: ws[/ws][5] text-message start
ws[/ws][5] frame[0] start[1447]
VSM
Connected clients: 1 / 1 total
  • the next click with data "dd" produces:
ndex: 0, len: 1447, final: 1, opcode: 1, framelen: 4
ws[/ws][5] frame[0] text[0 - 379]: ws[/ws][5] text-message start
ws[/ws][5] frame[0] start[1447]
��dd
  • here the data is corrupted...

I'm using

  • a D1 mini (ESP8266)
  • PlatformIO
  • Visual Code
  • MacOS (M4) 26.2 (25C56)
  • Using this libraries:
    Dependency Graph
    |-- ESP8266WiFi @ 1.0
    |-- ESPAsyncTCP @ 2.0.0
    |-- ESPAsyncWebServer @ 3.9.6
    Building in debug mode

Thanks

Peter

Stack Trace

No Stack Trace, cause the application did not crash..

Minimal Reproductible Example (MRE)

Source code:

// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright 2016-2026 Hristo Gochkov, Mathieu Carbou, Emil Muratov, Will Miles

//
// WebSocket example
//

#include <Arduino.h>
#if defined(ESP32) || defined(LIBRETINY)
#include <AsyncTCP.h>
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#elif defined(TARGET_RP2040) || defined(TARGET_RP2350) || defined(PICO_RP2040) || defined(PICO_RP2350)
#include <RPAsyncTCP.h>
#include <WiFi.h>
#endif

#include <ESPAsyncWebServer.h>

static const char *htmlContent PROGMEM = R"(
<!DOCTYPE html>
<html>
<head>
  <title>WebSocket</title>
</head>
<body>
  <h1>WebSocket Example</h1>
  <p>Open your browser console!</p>
  <input type="text" id="message" placeholder="Type a message">
  <button onclick='sendMessage()'>Send</button>
  <script>
    var ws = new WebSocket('ws://192.168.4.1/ws');
    ws.onopen = function() {
      console.log("WebSocket connected");
    };
    ws.onmessage = function(event) {
      console.log("WebSocket message: " + event.data);
    };
    ws.onclose = function() {
      console.log("WebSocket closed");
    };
    ws.onerror = function(error) {
      console.log("WebSocket error: " + error);
    };
    function sendMessage() {
      var message = document.getElementById("message").value;
      ws.send(message);
      console.log("WebSocket sent: " + message);
    }
  </script>
</body>
</html>
  )";
static const size_t htmlContentLength = strlen_P(htmlContent);

static AsyncWebServer server(80);
static AsyncWebSocket ws("/ws");

void setup() {
  Serial.begin(115200);

#if ASYNCWEBSERVER_WIFI_SUPPORTED
  WiFi.mode(WIFI_AP);
  WiFi.softAP("esp-captive");
#endif

  // serves root html page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(200, "text/html", (const uint8_t *)htmlContent, htmlContentLength);
  });

  //
  // Run in terminal 1: websocat ws://192.168.4.1/ws => should stream data
  // Run in terminal 2: websocat ws://192.168.4.1/ws => should stream data
  // Run in terminal 3: websocat ws://192.168.4.1/ws => should fail:
  //
  // To send a message to the WebSocket server:
  //
  // echo "Hello!" | websocat ws://192.168.4.1/ws
  //
  ws.onEvent([](AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
    (void)len;

    if (type == WS_EVT_CONNECT) {
      ws.textAll("new client connected");
      Serial.println("ws connect");
      client->setCloseClientOnQueueFull(false);
      client->ping();

    } else if (type == WS_EVT_DISCONNECT) {
      ws.textAll("client disconnected");
      Serial.println("ws disconnect");

    } else if (type == WS_EVT_ERROR) {
      Serial.println("ws error");

    } else if (type == WS_EVT_PONG) {
      Serial.println("ws pong");

    } else if (type == WS_EVT_DATA) {
      AwsFrameInfo *info = (AwsFrameInfo *)arg;
      Serial.printf("index: %" PRIu64 ", len: %" PRIu64 ", final: %" PRIu8 ", opcode: %" PRIu8 ", framelen: %d\n", 
        info->index, 
        info->len, 
        info->final, 
        info->opcode,
        len
    );
      String msg = "";
      if (info->final && info->index == 0 && info->len == len) {
        if (info->opcode == WS_TEXT) {
          data[len] = 0;
          Serial.printf("ws text: %s\n", (char *)data);
          client->ping();
        }
      } else {
        if(info->index == 0){
        if(info->num == 0)
          os_printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary");
        os_printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len);
      }

      os_printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT)?"text":"binary", info->index, info->index + len);
      if(info->message_opcode == WS_TEXT){
        data[len] = 0;
        os_printf("%s\n", (char*)data);
      } else {
        for(size_t i=0; i < len; i++){
          os_printf("%02x ", data[I]);
        }
        os_printf("\n");
      }

      if((info->index + len) == info->len){
        os_printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len);
        if(info->final){
          os_printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary");
          if(info->message_opcode == WS_TEXT)
            client->text("I got your text message");
          else
            client->binary("I got your binary message");
        }
      }
      }
    }
  });

  // shows how to prevent a third WS client to connect
  server.addHandler(&ws).addMiddleware([](AsyncWebServerRequest *request, ArMiddlewareNext next) {
    // ws.count() is the current count of WS clients: this one is trying to upgrade its HTTP connection
    if (ws.count() > 1) {
      // if we have 2 clients or more, prevent the next one to connect
      request->send(503, "text/plain", "Server is busy");
    } else {
      // process next middleware and at the end the handler
      next();
    }
  });

  server.addHandler(&ws);

  server.begin();
}

static uint32_t lastWS = 0;
static uint32_t deltaWS = 100;

static uint32_t lastHeap = 0;

void loop() {
  uint32_t now = millis();

  if (now - lastWS >= deltaWS) {
    ws.printfAll("kp%.4f", (10.0 / 3.0));
    lastWS = millis();
  }

  if (now - lastHeap >= 2000) {
    Serial.printf("Connected clients: %u / %u total\n", ws.count(), ws.getClients().size());

    // this can be called to also set a soft limit on the number of connected clients
    ws.cleanupClients(2);  // no more than 2 clients

#ifdef ESP32
    Serial.printf("Free heap: %" PRIu32 "\n", ESP.getFreeHeap());
#endif
    lastHeap = now;
  }
}

Test data:

{
    "logToSerial": true,
    "traceMode": false,
    "devicename": "LSC-device",
    "devicepwd": "admin-geheim",
    "autorestart": "86400",
    
    "wifi": {
        "ap_channel": 3,
        "ap_hide": false,
        "bssid": "aa:bb:33:22:11:fe",
        "ap_ssid": "LSC-8eaa2c44",
        "ap_mode": "0",
        "dhcp": true,
        "fallback": false,
        "ssid": "WiFiOnICE",
        "wifi_pwd": "JoJoBaOel",
        "hostname": "LSC-Device"   
    },
    "dewswitch": {
        "dewdelta": 5.2,
        "hysteresis": 1.5,
        "min_outdoor": -10.3,
        "min_indoor": 10.1
    },
    "sensor": {
        "adjust_humidity": 5,
        "adjust_temp": -0.2,
        "physical": true,
        "web_key": "33445566778899abcdef",
        "web_lat": "23.556778",
        "web_long": "8.553641"
    },
    "sensorOD": {
        "adjust_humidity": 0.3,
        "adjust_temp": 0.5,
        "physical": false,
        "web_key": "33445566778899abcdef",
        "web_lat": "23.556778",
        "web_long": "8.553641"
    },
    "mqtt" : {
        "enabled": false,
        "autotopic": false,
        "host": "mqtt-host",
        "port": 1883,
        "syncrate": 60,
        "topic": "",
        "user": "",
        "passwd": "",
        "useha": false
    },
    "rf433": {
        "enabled": true,
        "msgs": [
            { "on": 4333356,"msg": 1, "type":1 },
            { "on": 4333362,"msg": 0, "type":0 }
        ]
        }
}

I confirm that:

  • I have read the documentation.
  • I have searched for similar discussions.
  • I have searched for similar issues.
  • I have looked at the examples.
  • I have upgraded to the lasted version of ESPAsyncWebServer (and AsyncTCP for ESP32).

Activity

  1. mathieucarbou commented on Feb 3, 2026

    @mathieucarbou
    Member

    HI @LSC-Labs , were you able to reproduce the issue on esp32 too by any chance ?

  2. LSC-Labs commented on Feb 3, 2026

    @LSC-Labs
    Author

    Yes I tried the same with an ESP32

    Sending the long message shows me a larger frame (1428 instead of 528) - but basically the same behavior ... ( I doubled the test data to be sure to get enough data inside )
    output on console is :

    Connected clients: 1 / 1 total
    Free heap: 236476
    index: 0, len: 2897, final: 1, opcode: 1, framelen: 1428
    ws[/ws][2] text-message start
    ws[/ws][2] frame[0] start[2897]
    ws[/ws][2] frame[0] text[0 - 1428]: {     "logToSerial": true,     "traceMode": false,     "devicename": "LSC-device",     "devicepwd": "admin-geheim",     "autorestart": "86400",          "wifi": {         "ap_channel": 3,         "ap_hide": false,         "bssid": "aa:bb:33:22:11:fe",         "ap_ssid": "LSC-8eaa2c44",         "ap_mode": "0",         "dhcp": true,         "fallback": false,         "ssid": "WiFiOnICE",         "wifi_pwd": "JoJoBaOel",         "hostname": "LSC-Device"        },     "dewswitch": {         "dewdelta": 5.2,         "hysteresis": 1.5,         "min_outdoor": -10.3,         "min_indoor": 10.1     },     "sensor": {         "adjust_humidity": 5,         "adjust_temp": -0.2,         "physical": true,         "web_key": "33445566778899abcdef",         "web_lat": "23.556778",         "web_long": "8.553641"     },     "sensorOD": {         "adjust_humidity": 0.3,         "adjust_temp": 0.5,         "physical": false,         "web_key": "33445566778899abcdef",         "web_lat": "23.556778",         "web_long": "8.553641"     },     "mqtt" : {         "enabled": false,         "autotopic": false,         "host": "mqtt-host",         "port": 1883,         "syncrate": 60,         "topic": "",         "user": "",         "passwd": "",         "useha": false     },     "rf433": {         "enabled": true,         "msgs": [             { "on": 4333356,"msg": 1, "type":1 },             { "on": 4333362,"msg": 0, "type":0 }   
    index: 0, len: 2897, final: 1, opcode: 1, framelen: 1432
    ws[/ws][2] text-message start
    ws[/ws][2] frame[0] start[2897]
    ws[/ws][2] frame[0] text[0 - 1432]: 
    index: 0, len: 2897, final: 1, opcode: 1, framelen: 29
    ws[/ws][2] text-message start
    ws[/ws][2] frame[0] start[2897]
    ws[/ws][2] frame[0] text[0 - 29]: PGVC␐␂        Y
    Connected clients: 1 / 1 total
    

    After this call I immediately send also the "dd" input with the result:
    (as you can see, also corrupted)

    
    Free heap: 236476
    index: 0, len: 2897, final: 1, opcode: 1, framelen: 4
    ws[/ws][2] text-message start
    ws[/ws][2] frame[0] start[2897]
    ws[/ws][2] frame[0] text[0 - 4]: ␄:dd
    Connected clients: 1 / 1 total
    Free heap: 236476
    

    After a while (without input - while I'm writing this test) I get the following messages - repeating:

    [666084][E][AsyncWebSocket.cpp:436] _queueMessage(): Too many messages queued: discarding new message
    

    The build is using:

    PLATFORM: Espressif 32 (6.9.0) > AZ-Delivery ESP-32 Dev Kit C V4
    HARDWARE: ESP32 240MHz, 520KB RAM, 4MB Flash
    ...
    Scanning dependencies...
    Dependency Graph
    |-- WiFi @ 2.0.0
    |-- ESPAsyncWebServer @ 3.9.6
    |-- AsyncTCP @ 3.4.10
    Building in debug mode
    

    The chip is an ESP32 WROOM-32 (C4)

  3. LSC-Labs commented on Feb 3, 2026

    @LSC-Labs
    Author

    I forgot, I have to change the source code and replace the "os_printf" with "Serial.printf", cause the compiler could not find the definition... but I assume, this has no effect on.
    Thx
    Peter

  4. deleted a comment from coderabbitai on Feb 3, 2026
  5. mathieucarbou commented on Feb 3, 2026

    @mathieucarbou
    Member

    [666084][E][AsyncWebSocket.cpp:436] _queueMessage(): Too many messages queued: discarding new message

    when a ws message is sent, it does in a queue. if the async_tcp task is not able to process the sending faster than messages are enqueued, then the queue overflows.

    I can reproduce the bug.

    The bug was introduced in PR #353.

    Safari sends an incomplete fragmented data for the mask so somebody did a PR to fix that but sadly broke backward compatibility because of the use of flag to keep track of the by count.

    My fix sadly used the index which breaks fragmented frames.

    Will find a way to fix it...

  6. added theissue type on Feb 3, 2026
  7. self-assigned this
    on Feb 3, 2026
  8. LSC-Labs commented on Feb 3, 2026

    @LSC-Labs
    Author

    Great, thank you ....
    ... only to describe correctly, the tests I made, were done with
    "Google Chrome - Version 144.0.7559.110 (Offizieller Build) (arm64)".
    ... the enqueued message I notified happened while writing the description of the error (in Safari).
    I did not seen them before...
    At this point, my network was connected to the access point the device opened (192.168.4.1) - without internet connection... so maybe this was a side effect.

    The main problem is the index/frame number/final flag - also as the corrupted data after the first frame was received in the function.
    Would be great if you find a solution for it...

  9. added a commit that references this issue on Feb 3, 2026
    b16f022
  10. mathieucarbou commented on Feb 3, 2026

    @mathieucarbou
    Member

    @LSC-Labs : could you please test by pointing to branch https://github.com/ESP32Async/ESPAsyncWebServer#issue-353 (messed up with the name lol) from PR #383 ?

  11. added 2 commits that reference this issue on Feb 3, 2026
    ad9be24
    5d3e467
  12. LSC-Labs commented on Feb 4, 2026

    @LSC-Labs
    Author

    Result of https://github.com/ESP32Async/ESPAsyncWebServer#issue-353

    • running again on ESP8266 D1-Mini...
      ... works as expected (maybe I did not get the meaning of the final flag - I expected the last frame - but
      it works as described also in the example...
    Connected clients: 1 / 1 total
    index: 0, len: 1447, final: 1, opcode: 1, framelen: 528
    ws[/ws][1] text-message start
    ws[/ws][1] frame[0] start[1447]
    ws[/ws][1] frame[0] text[0 - 528]: {     "logToSerial": true,     "traceMode": false,     "devicename": "LSC-device",     "devicepwd": "admin-geheim",     "autorestart": "86400",          "wifi": {         "ap_channel": 3,         "ap_hide": false,         "bssid": "aa:bb:33:22:11:fe",         "ap_ssid": "LSC-8eaa2c44",         "ap_mode": "0",         "dhcp": true,         "fallback": false,         "ssid": "WiFiOnICE",         "wifi_pwd": "JoJoBaOel",         "hostname": "LSC-Device"        },     "dewswitch": {         "dewdelta": 5.2,         "hysteresis
    index: 528, len: 1447, final: 1, opcode: 1, framelen: 536
    ws[/ws][1] frame[0] text[528 - 1064]: ": 1.5,         "min_outdoor": -10.3,         "min_indoor": 10.1     },     "sensor": {         "adjust_humidity": 5,         "adjust_temp": -0.2,         "physical": true,         "web_key": "33445566778899abcdef",         "web_lat": "23.556778",         "web_long": "8.553641"     },     "sensorOD": {         "adjust_humidity": 0.3,         "adjust_temp": 0.5,         "physical": false,         "web_key": "33445566778899abcdef",         "web_lat": "23.556778",         "web_long": "8.553641"     },     "mqtt" : {         "enabled"
    index: 1064, len: 1447, final: 1, opcode: 1, framelen: 383
    ws[/ws][1] frame[0] text[1064 - 1447]: : false,         "autotopic": false,         "host": "mqtt-host",         "port": 1883,         "syncrate": 60,         "topic": "",         "user": "",         "passwd": "",         "useha": false     },     "rf433": {         "enabled": true,         "msgs": [             { "on": 4333356,"msg": 1, "type":1 },             { "on": 4333362,"msg": 0, "type":0 }         ]         } }
    ws[/ws][1] frame[0] end[1447]
    ws[/ws][1] text-message end
    Connected clients: 1 / 1 total
    
  13. LSC-Labs commented on Feb 4, 2026

    @LSC-Labs
    Author

    Result of https://github.com/ESP32Async/ESPAsyncWebServer#issue-353

    • It is also working in the ESP32 environment:
    Connected clients: 1 / 1 total
    Free heap: 236448
    index: 0, len: 2897, final: 1, opcode: 1, framelen: 1428
    ws[/ws][1] text-message start
    ws[/ws][1] frame[0] start[2897]
    ws[/ws][1] frame[0] text[0 - 1428]: {     "logToSerial": true,     "traceMode": false,     "devicename": "LSC-device",     "devicepwd": "admin-geheim",     "autorestart": "86400",          "wifi": {         "ap_channel": 3,         "ap_hide": false,         "bssid": "aa:bb:33:22:11:fe",         "ap_ssid": "LSC-8eaa2c44",         "ap_mode": "0",         "dhcp": true,         "fallback": false,         "ssid": "WiFiOnICE",         "wifi_pwd": "JoJoBaOel",         "hostname": "LSC-Device"        },     "dewswitch": {         "dewdelta": 5.2,         "hysteresis": 1.5,         "min_outdoor": -10.3,         "min_indoor": 10.1     },     "sensor": {         "adjust_humidity": 5,         "adjust_temp": -0.2,         "physical": true,         "web_key": "33445566778899abcdef",         "web_lat": "23.556778",         "web_long": "8.553641"     },     "sensorOD": {         "adjust_humidity": 0.3,         "adjust_temp": 0.5,         "physical": false,         "web_key": "33445566778899abcdef",         "web_lat": "23.556778",         "web_long": "8.553641"     },     "mqtt" : {         "enabled": false,         "autotopic": false,         "host": "mqtt-host",         "port": 1883,         "syncrate": 60,         "topic": "",         "user": "",         "passwd": "",         "useha": false     },     "rf433": {         "enabled": true,         "msgs": [             { "on": 4333356,"msg": 1, "type":1 },             { "on": 4333362,"msg": 0, "type":0 }   
    index: 1428, len: 2897, final: 1, opcode: 1, framelen: 1436
    ws[/ws][1] frame[0] text[1428 - 2864]:       ]         } }+++{     "logToSerial": true,     "traceMode": false,     "devicename": "LSC-device",     "devicepwd": "admin-geheim",     "autorestart": "86400",          "wifi": {         "ap_channel": 3,         "ap_hide": false,         "bssid": "aa:bb:33:22:11:fe",         "ap_ssid": "LSC-8eaa2c44",         "ap_mode": "0",         "dhcp": true,         "fallback": false,         "ssid": "WiFiOnICE",         "wifi_pwd": "JoJoBaOel",         "hostname": "LSC-Device"        },     "dewswitch": {         "dewdelta": 5.2,         "hysteresis": 1.5,         "min_outdoor": -10.3,         "min_indoor": 10.1     },     "sensor": {         "adjust_humidity": 5,         "adjust_temp": -0.2,         "physical": true,         "web_key": "33445566778899abcdef",         "web_lat": "23.556778",         "web_long": "8.553641"     },     "sensorOD": {         "adjust_humidity": 0.3,         "adjust_temp": 0.5,         "physical": false,         "web_key": "33445566778899abcdef",         "web_lat": "23.556778",         "web_long": "8.553641"     },     "mqtt" : {         "enabled": false,         "autotopic": false,         "host": "mqtt-host",         "port": 1883,         "syncrate": 60,         "topic": "",         "user": "",         "passwd": "",         "useha": false     },     "rf433": {         "enabled": true,         "msgs": [             { "on": 4333356,"msg": 1, "type":1 },             { "on": 4333362,"msg": 0,
    index: 2864, len: 2897, final: 1, opcode: 1, framelen: 33
    ws[/ws][1] frame[0] text[2864 - 2897]:  "type":0 }         ]         } }
    ws[/ws][1] frame[0] end[2897]
    ws[/ws][1] text-message end
    Connected clients: 1 / 1 total
    Free heap: 236448
    
  14. mathieucarbou commented on Feb 4, 2026

    @mathieucarbou
    Member
    • ... works as expected (maybe I did not get the meaning of the final flag - I expected the last frame - but

    this final flag is weird indeed. I would have expected it to for like the upload handler, which means only set to 1 when the final fragment is received.

    But instead, it is 1 for the last websocket frame. and a websocket frame can be up to 2^63 bytes long if I am not making a mistake. In the header:

    typedef struct {
      /** Message type as defined by enum AwsFrameType.
         * Note: Applications will only see WS_TEXT and WS_BINARY.
         * All other types are handled by the library. */
      uint8_t message_opcode;
      /** Frame number of a fragmented message. */
      uint32_t num;
      /** Is this the last frame in a fragmented message ?*/
      uint8_t final;
      /** Is this frame masked? */
      uint8_t masked;
      /** Message type as defined by enum AwsFrameType.
         * This value is the same as message_opcode for non-fragmented
         * messages, but may also be WS_CONTINUATION in a fragmented message. */
      uint8_t opcode;
      /** Length of the current frame.
         * This equals the total length of the message if num == 0 && final == true */
      uint64_t len;
      /** Mask key */
      uint8_t mask[4];
      /** Offset of the data inside the current frame. */
      uint64_t index;
    } AwsFrameInfo;

    We have 3 levels:

    • A WebSocket message
    • Which can be split into WebSocket frames
    • And any of that, even control frames, can be sent fragmented. For example Safari sends only a few bytes for some control frames then sends the rest.

    So in theory, on an MCU, I would expect that everyone should see final == 1, and frame count should not increase, which is also the flag read from the websocket spec in the header of a starting frame.

    Only TCP fragmentation could happen.

  15. mathieucarbou commented on Feb 4, 2026

    @mathieucarbou
    Member

    The rest of the team will review hopefully this week and if that's the case I will be able to issue a release this week-end.

  16. mathieucarbou commented on Feb 4, 2026

    @mathieucarbou
    Member

    Note in your trace:

    index: 1064, len: 1447, final: 1, opcode: 1, framelen: 383

    framelen is not a frame length but instead this is a TCP fragment of the same websocket frame ;-)

  17. added a commit that references this issue on Feb 8, 2026
    406147f
  18. jfandl325 commented on Feb 12, 2026

    @jfandl325

    Thanks for the fix on this. I was banging my head on why my JSON wasn't working from one of my devices, yet others were (using WebSocketsClient). My device (esp32p4) running esp_websocket_client was sending the JSON to an esp32 nano and it was fragmenting the message into two frames, 2 bytes for the first one every time and then the remainder of the frame (no matter the size I used (18 bytes, 63 bytes, 88 bytes), but the contents was garbage. I installed the latest commit and now it shows up as one frame instead of two, complete, JSON is valid again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions