MbedTLS unknown error unsolved for ESP32-IDF?

Hello guys,

I’m working on my first IOT projects with ESP32 boards and AWS IOT core gateway and I’m stuck with really annoying MbedTLS unknwown erros (“UNKNOWN ERROR CODE” 004C and 004E ) .
Related with mqqt ssl_client :
_handle_error(): [data_to_read():270]: (-76) UNKNOWN ERROR CODE (004C)

I’ve browsed many pages on the web, like this interesting one : mbedtls problem with libcurl port to ESP32 · Issue #1327 · curl/curl · GitHub

but I did not get any working solution to solve my simple Iot publish app with esp32 and AWS IOt core. I’m sure there are many similar projects on the web and I would be really interested if someone have found a solution !

Thanks a lot.

Refer to source code

So “something” has gone wrong with sending data into the socket.

Without code that reproduces the problem you have, it’s however very hard to help you.

Thanks @maxgerhardt for error definition sources, here is my code: (i’m using last release of platfo

platformio.ini

env:heltec_wifi_kit_32]
platform = espressif32
framework = arduino
board = heltec_wifi_kit_32
upload_port = /dev/cu.SLAB_USBtoUART
monitor_port = /dev/cu.SLAB_USBtoUART
monitor_speed = 115200
lib_deps = 
	256dpi/MQTT@^2.4.7
	bblanchon/ArduinoJson@^6.16.1

main.cpp

#include "conf.h"
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <iot.h>
#include <ArduinoJson.h>

WiFiClientSecure secureClient = WiFiClientSecure();
PubSubClient mqttClient(secureClient);
IOT iotclient(secureClient, mqttClient);

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

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.println("Failed to connect to WiFi");
    sleep(5);
  }
  Serial.print("Connected to WiFi with IP address ");
  Serial.println(WiFi.localIP());
  iotclient.setup();
  iotclient.print_on_publish(true);
}

void loop()
{
  const char *payload = "{'val1':12,'val2':'test'}";

  if (iotclient.publish("kludaryer/pub", (const uint8_t*)payload,strlen(payload))) {
    Serial.println("Successfully posted ");
  }
  else { Serial.println("Failed to post to MQTT"); }
  delay(1000);
}

Once the app launched, after few successful posts (so it validates the SSL connection to AWS IOT gateway with certificate) I got some errors like these and then the app is unable to reconnect.

Connected to WiFi with IP address 192.168.1.87
Successfully posted 
...
[E][ssl_client.cpp:33] _handle_error(): [start_ssl_client():199]: (-76) UNKNOWN ERROR CODE (004C)
[E][WiFiClientSecure.cpp:132] connect(): start_ssl_client: -76
[E][ssl_client.cpp:87] start_ssl_client(): Connect to Server failed!
[E][WiFiClientSecure.cpp:132] connect(): start_ssl_client: -1
[E][ssl_client.cpp:87] start_ssl_client(): Connect to Server failed!
[E][WiFiClientSecure.cpp:132] connect(): start_ssl_client: -1
[E][ssl_client.cpp:87] start_ssl_client(): Connect to Server failed!

Okay so it seems either the TLS library or MQTT library is at fault. The error is already known and reported in the library: SSL not working properly disconnects after few seconds and never connects back · Issue #154 · 256dpi/arduino-mqtt · GitHub.

You may want to try an earlier espressif32 platform version like

platform = espressif32@1.7.0

to get an earlier Arduino core which may not yet have this problem. See list of releases Releases · platformio/platform-espressif32 · GitHub.

You may also try to use the current platform version and enable debugging output as per Espressif 32 — PlatformIO latest documentation ,e.g.

build_flags = -DCORE_DEBUG_LEVEL=5

for the highest debugging level, and then check the logs before the error to get an indication of what’s happening, either in the TLS stack or in the library code.

Lastly, a reference check with the Arduino IDE should be done to see if the problem is general or PIO specific.

1 Like

Also in this error case you amy want to call .disconnect(); on the MQTT client object as the previous issue link suggests.

Thanks @maxgerhardt for your quick and useful answer :wink: I will check with older version of espressif32 and check also with higher debug level.

sorry but you mean I’ve to disconnect WIFI before a new attempt ?

No as SSL not working properly disconnects after few seconds and never connects back · Issue #154 · 256dpi/arduino-mqtt · GitHub says on mqttClient.

Oh I see sorry.
regarding my first point, I’ve recompiled with earlier version of espressif and enabled the log level.
It seems ‘more’ stable but still get the errors but I’ve some debug info now :slight_smile:

...
[V][ssl_client.cpp:243] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:243] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:53] start_ssl_client(): Free internal heap before TLS 218032
[V][ssl_client.cpp:55] start_ssl_client(): Starting socket
[V][ssl_client.cpp:88] start_ssl_client(): Seeding the random number generator
[V][ssl_client.cpp:97] start_ssl_client(): Setting up the SSL/TLS structure...
[V][ssl_client.cpp:110] start_ssl_client(): Loading CA cert
[V][ssl_client.cpp:158] start_ssl_client(): Loading CRT cert
[V][ssl_client.cpp:165] start_ssl_client(): Loading private key
[V][ssl_client.cpp:175] start_ssl_client(): Setting hostname for TLS session...
[V][ssl_client.cpp:190] start_ssl_client(): Performing the SSL/TLS handshake...
[D][ssl_client.cpp:203] start_ssl_client(): Protocol is TLSv1.2 Ciphersuite is TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256
[D][ssl_client.cpp:205] start_ssl_client(): Record expansion is 29
[V][ssl_client.cpp:211] start_ssl_client(): Verifying peer X.509 certificate...
[V][ssl_client.cpp:220] start_ssl_client(): Certificate verified.
[V][ssl_client.cpp:235] start_ssl_client(): Free internal heap after TLS 172800
[V][ssl_client.cpp:274] send_ssl_data(): Writing HTTP request...
[V][ssl_client.cpp:274] send_ssl_data(): Writing HTTP request...
Successfully posted 
[V][ssl_client.cpp:243] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:243] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:53] start_ssl_client(): Free internal heap before TLS 218032
[V][ssl_client.cpp:55] start_ssl_client(): Starting socket
[V][ssl_client.cpp:88] start_ssl_client(): Seeding the random number generator
[V][ssl_client.cpp:97] start_ssl_client(): Setting up the SSL/TLS structure...
[V][ssl_client.cpp:110] start_ssl_client(): Loading CA cert
[V][ssl_client.cpp:158] start_ssl_client(): Loading CRT cert
[V][ssl_client.cpp:165] start_ssl_client(): Loading private key
[V][ssl_client.cpp:175] start_ssl_client(): Setting hostname for TLS session...
[V][ssl_client.cpp:190] start_ssl_client(): Performing the SSL/TLS handshake...
[D][ssl_client.cpp:203] start_ssl_client(): Protocol is TLSv1.2 Ciphersuite is TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256
[D][ssl_client.cpp:205] start_ssl_client(): Record expansion is 29
[V][ssl_client.cpp:211] start_ssl_client(): Verifying peer X.509 certificate...
[V][ssl_client.cpp:220] start_ssl_client(): Certificate verified.
[V][ssl_client.cpp:235] start_ssl_client(): Free internal heap after TLS 172812
[V][ssl_client.cpp:274] send_ssl_data(): Writing HTTP request...
[D][WiFiGeneric.cpp:342] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:357] _eventCallback(): Reason: 204 - HANDSHAKE_TIMEOUT
[D][WiFiGeneric.cpp:342] _eventCallback(): Event: 0 - WIFI_READY
[D][WiFiGeneric.cpp:342] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:342] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:342] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:342] _eventCallback(): Event: 7 - STA_GOT_IP
[D][WiFiGeneric.cpp:385] _eventCallback(): STA IP: 192.168.1.87, MASK: 255.255.255.0, GW: 192.168.1.1
[E][ssl_client.cpp:33] handle_error(): UNKNOWN ERROR CODE (004C)
[E][ssl_client.cpp:35] handle_error(): MbedTLS message code: -76
[V][ssl_client.cpp:243] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:243] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:53] start_ssl_client(): Free internal heap before TLS 218624
[V][ssl_client.cpp:55] start_ssl_client(): Starting socket
[V][ssl_client.cpp:88] start_ssl_client(): Seeding the random number generator
[V][ssl_client.cpp:97] start_ssl_client(): Setting up the SSL/TLS structure...
[V][ssl_client.cpp:110] start_ssl_client(): Loading CA cert
[V][ssl_client.cpp:158] start_ssl_client(): Loading CRT cert
[V][ssl_client.cpp:165] start_ssl_client(): Loading private key
[V][ssl_client.cpp:175] start_ssl_client(): Setting hostname for TLS session...
[V][ssl_client.cpp:190] start_ssl_client(): Performing the SSL/TLS handshake...
[D][ssl_client.cpp:203] start_ssl_client(): Protocol is TLSv1.2 Ciphersuite is TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256
[D][ssl_client.cpp:205] start_ssl_client(): Record expansion is 29
[V][ssl_client.cpp:211] start_ssl_client(): Verifying peer X.509 certificate...
[V][ssl_client.cpp:220] start_ssl_client(): Certificate verified.
[V][ssl_client.cpp:235] start_ssl_client(): Free internal heap after TLS 172976
[V][ssl_client.cpp:274] send_ssl_data(): Writing HTTP request...
[V][ssl_client.cpp:274] send_ssl_data(): Writing HTTP request...
Successfully posted 
...

more info to crunch now to get rif of that issue. Seems that a ‘Event: 5 - STA_DISCONNECTED’ occured and is at the origin of the issue

Could it be only disconnection from my link (WIFI or some timeout for DNS resolution…? )

Are you doing anything in your code that causes the SSL connection to be closed after posting? Since you haven’t posted iot.h and related code I can’t judge.

Here the ESP32 is disconnected from the WiFi. But the reason is “HANDSHAKE_TIMEOUT”, which means it during the association / WPA2 handshake / connecting to the WiFi an error has occured. That’s weird. Are you disconnecting / reconnecting from the WiFi yourself?

Do the error messages change when using the latest espressif32 platform version?

If I put back the latest espressif release with log enabled, I got the issue but once here the app is unable to reconnect compared with the 1.7 release where we could post successfuly afterwards withour restarting the app.

In this test with the latest release of espressif, we could see also the other error code 0x004E but I guess the main reason of these both issues are due to the disconnection.

--- Available filters and text transformations: colorize, debug, default, direct, esp32_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at http://bit.ly/pio-monitor-filters
--- Miniterm on /dev/cu.SLAB_USBtoUART  115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
Connected to WiFi with IP address 192.168.1.87
[V][ssl_client.cpp:56] start_ssl_client(): Free internal heap before TLS 201440
[V][ssl_client.cpp:58] start_ssl_client(): Starting socket
[V][ssl_client.cpp:93] start_ssl_client(): Seeding the random number generator
[V][ssl_client.cpp:102] start_ssl_client(): Setting up the SSL/TLS structure...
[V][ssl_client.cpp:115] start_ssl_client(): Loading CA cert
[V][ssl_client.cpp:163] start_ssl_client(): Loading CRT cert
[V][ssl_client.cpp:170] start_ssl_client(): Loading private key
[V][ssl_client.cpp:180] start_ssl_client(): Setting hostname for TLS session...
[V][ssl_client.cpp:195] start_ssl_client(): Performing the SSL/TLS handshake...
[D][ssl_client.cpp:208] start_ssl_client(): Protocol is TLSv1.2 Ciphersuite is TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256
[D][ssl_client.cpp:210] start_ssl_client(): Record expansion is 29
[V][ssl_client.cpp:216] start_ssl_client(): Verifying peer X.509 certificate...
[V][ssl_client.cpp:225] start_ssl_client(): Certificate verified.
[V][ssl_client.cpp:240] start_ssl_client(): Free internal heap after TLS 155036
[V][ssl_client.cpp:279] send_ssl_data(): Writing HTTP request...
[V][ssl_client.cpp:279] send_ssl_data(): Writing HTTP request...
Successfully posted 
[V][ssl_client.cpp:248] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:248] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:56] start_ssl_client(): Free internal heap before TLS 200032
[V][ssl_client.cpp:58] start_ssl_client(): Starting socket
[V][ssl_client.cpp:93] start_ssl_client(): Seeding the random number generator
[V][ssl_client.cpp:102] start_ssl_client(): Setting up the SSL/TLS structure...
[V][ssl_client.cpp:115] start_ssl_client(): Loading CA cert
[V][ssl_client.cpp:163] start_ssl_client(): Loading CRT cert
[V][ssl_client.cpp:170] start_ssl_client(): Loading private key
[V][ssl_client.cpp:180] start_ssl_client(): Setting hostname for TLS session...
[V][ssl_client.cpp:195] start_ssl_client(): Performing the SSL/TLS handshake...
[D][ssl_client.cpp:208] start_ssl_client(): Protocol is TLSv1.2 Ciphersuite is TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256
[D][ssl_client.cpp:210] start_ssl_client(): Record expansion is 29
[V][ssl_client.cpp:216] start_ssl_client(): Verifying peer X.509 certificate...
[V][ssl_client.cpp:225] start_ssl_client(): Certificate verified.
[V][ssl_client.cpp:240] start_ssl_client(): Free internal heap after TLS 154884
[V][ssl_client.cpp:279] send_ssl_data(): Writing HTTP request...
[V][ssl_client.cpp:279] send_ssl_data(): Writing HTTP request...
Successfully posted 
[V][ssl_client.cpp:248] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:248] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:56] start_ssl_client(): Free internal heap before TLS 199928
[V][ssl_client.cpp:58] start_ssl_client(): Starting socket
[V][ssl_client.cpp:93] start_ssl_client(): Seeding the random number generator
[V][ssl_client.cpp:102] start_ssl_client(): Setting up the SSL/TLS structure...
[V][ssl_client.cpp:115] start_ssl_client(): Loading CA cert
[V][ssl_client.cpp:163] start_ssl_client(): Loading CRT cert
[V][ssl_client.cpp:170] start_ssl_client(): Loading private key
[V][ssl_client.cpp:180] start_ssl_client(): Setting hostname for TLS session...
[V][ssl_client.cpp:195] start_ssl_client(): Performing the SSL/TLS handshake...
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:353] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[E][ssl_client.cpp:33] _handle_error(): [start_ssl_client():199]: (-78) UNKNOWN ERROR CODE (004E)
[E][WiFiClientSecure.cpp:132] connect(): start_ssl_client: -78
[V][ssl_client.cpp:248] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:56] start_ssl_client(): Free internal heap before TLS 196104
[V][ssl_client.cpp:58] start_ssl_client(): Starting socket
[E][ssl_client.cpp:87] start_ssl_client(): Connect to Server failed!
[E][WiFiClientSecure.cpp:132] connect(): start_ssl_client: -1
[V][ssl_client.cpp:248] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:56] start_ssl_client(): Free internal heap before TLS 196008
[V][ssl_client.cpp:58] start_ssl_client(): Starting socket
[E][ssl_client.cpp:87] start_ssl_client(): Connect to Server failed!
[E][WiFiClientSecure.cpp:132] connect(): start_ssl_client: -1
[V][ssl_client.cpp:248] stop_ssl_socket(): Cleaning SSL connection.
[V][ssl_client.cpp:56] start_ssl_client(): Free internal heap before TLS 195912
[V][ssl_client.cpp:58] start_ssl_client(): Starting socket
[E][ssl_client.cpp:87] start_ssl_client(): Connect to Server failed!
[E][WiFiClientSecure.cpp:132] connect(): start_ssl_client: -1
[V][ssl_client.cpp:248] stop_ssl_socket(): Cleaning SSL connection.

At the origin, I’ve ‘cloned’ a project with iot and pubsub source code, I do not have include these libraries from platformio homepage, may be these 2 libs are outdated and bugged. I will try to use the ‘normal’ way

Hm now it’s disconnected due to an… authentication expire? There is an issue Wifi not connected to the esp32 module. · Issue #2144 · espressif/arduino-esp32 · GitHub but people don’t have solutions besides restarting the router, updating the Arduino core (which only sometimes helped).

It definitely doesn’t look right that 1.) the connection is closed after every publish() according to the SSL messages and 2.) that you loose WiFi.

Maybe also try to not do any MQTT publishing but just connecting to the WiFi and see if you are kicked out.

@maxgerhardt as said in my previous message, I’ve done a new project based on the native and latest MQTT lib and not the iot/pusub directories I used before and with the latest espressif32… and it seems to work !

--- Available filters and text transformations: colorize, debug, default, direct, esp32_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at http://bit.ly/pio-monitor-filters
--- Miniterm on /dev/cu.SLAB_USBtoUART  115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
[D][ssl_client.cpp:208] start_ssl_client(): Protocol is TLSv1.2 Ciphersuite is TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256
[D][ssl_client.cpp:210] start_ssl_client(): Record expansion is 29
[V][ssl_client.cpp:216] start_ssl_client(): Verifying peer X.509 certificate...
[V][ssl_client.cpp:225] start_ssl_client(): Certificate verified.
[V][ssl_client.cpp:240] start_ssl_client(): Free internal heap after TLS 218624
[V][ssl_client.cpp:279] send_ssl_data(): Writing HTTP request...
AWS IoT Connected!
[V][ssl_client.cpp:279] send_ssl_data(): Writing HTTP request...
message posted
[V][ssl_client.cpp:248] stop_ssl_socket(): Cleaning SSL connection.
message posted
message posted
message posted
message posted
message posted
message posted
message posted
message posted
message posted
message posted
...

here is my new code:

main.cpp

#include "secrets.h"
#include <WiFiClientSecure.h>
#include <MQTTClient.h>
#include <ArduinoJson.h>
#include "WiFi.h"

#define AWS_IOT_PUBLISH_TOPIC   "kludaryer/pub"

WiFiClientSecure net = WiFiClientSecure();
MQTTClient client = MQTTClient(256);

void connectAWS()
{
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  Serial.println("Connecting to Wi-Fi");

  while (WiFi.status() != WL_CONNECTED){
    delay(500);
    Serial.print(".");
  }

  // Configure WiFiClientSecure to use the AWS IoT device credentials
  net.setCACert(AWS_CERT_CA);
  net.setCertificate(AWS_CERT_CRT);
  net.setPrivateKey(AWS_CERT_PRIVATE);

  // Connect to the MQTT broker on the AWS endpoint we defined earlier
  client.begin(AWS_IOT_ENDPOINT, 8883, net);

  // Create a message handler
  // client.onMessage(messageHandler);

  Serial.print("Connecting to AWS IOT");

  while (!client.connect(THINGNAME)) {
    Serial.print(".");
    delay(100);
  }

  if(!client.connected()){
    Serial.println("AWS IoT Timeout!");
    return;
  }

  // Subscribe to a topic
  // client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC);

  Serial.println("AWS IoT Connected!");
}

void publishMessage()
{
  const char *payload = "{'val1':12,'val2':'test'}";
  client.publish(AWS_IOT_PUBLISH_TOPIC, payload);
  Serial.println("message posted");
}

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

void loop() {
  publishMessage();
  // client.loop();
  delay(5000);
}

Sorry for having wasted your time with some old libs from older projects… hope it will help other devs in such context !

Thanks a lot for your help @maxgerhardt

Okay great that it works now, but you should still take care of potential errors returned by the publish function and then attempt a disconnect and reconnect, while printing the result of the lwmqtt_err_t lastError() member of function of the MQTTClient to be safe :slight_smile:

1 Like

something like that :slight_smile:

boolean publishMessage()
{
  const char *payload = "{'val1':12,'val2':'test'}";
  if (client.publish(AWS_IOT_PUBLISH_TOPIC, payload) == false) {
    // Erreur lors de l'envoi des données
    Serial.println("Error occured during publish!");
    switch(client.lastError()) {
      case LWMQTT_NETWORK_FAILED_CONNECT:
      case LWMQTT_NETWORK_TIMEOUT:
      case LWMQTT_NETWORK_FAILED_READ:
      case LWMQTT_NETWORK_FAILED_WRITE:
      case LWMQTT_CONNECTION_DENIED:
      case LWMQTT_PONG_TIMEOUT:
        // Reconnection needed
        // ...
        break;
    }
    return(false);
  } else {
    Serial.println("message published");
    return(true);
  }
}