ReadyMail.h autoclient example erratic behaviour

Refering to this topic (Oct 2025) where the author of this library (@Mobizt ) suggested testing with this example sketch from him:

ReadyMail/examples/Network/AutoClient/AutoClient.ino

This sketch is designed to send emails from authenticated email servers using either SSL (port 465), TLS (port 587) or palin text (port 25).

My webmail server uses port 587, and authentication works well as can be seen in the output from the serial monitor below.

However, more often then not does no email get sent. This erratic behaviour very much puzzles me because I cannot discover any rational explanation for this.

After a suggestion from @Mobizt last year I added this line of code at the end of the sendEmail function:

  smtp.stop();  // terminate connection https://forum.arduino.cc/t/readymail-h-example-autoclient-ino-error-sending-starttls-command/1409355/3

Serial monitor output (only those sessions where is shown "The Email is sent successfully" is the email succesfully received. In the monitor output below this was the case in 1 out of 5 or 6 or more sessions.

Connecting to Wi-Fi..................
Connected with IP: 192.168.1.208

ReadyMail, version 0.3.6
ReadyMail[smtp][1] Connecting to "webreus.email" via port 587...
ReadyMail[smtp][2] Sending greeting...
ReadyMail[smtp][3] Starting TLS...
ReadyMail[smtp][3] Performing TLS handshake...
ReadyMail[smtp][3] TLS handshake done
ReadyMail[smtp][2] Sending greeting...
ReadyMail[smtp][2] Service is ready
ReadyMail[smtp][5] Authenticating...
ReadyMail[smtp][5] The client is authenticated successfully
ReadyMail[smtp][11] Sending Email...
ReadyMail[smtp][11] Sending envelope...
ReadyMail[smtp][12] Sending headers...
ReadyMail[smtp][14] Sending multipart content (alternative)...
ReadyMail[smtp][14] Sending text/plain body...
ReadyMail[smtp][14] Sending text/html body...
ReadyMail[smtp][14] The Email is sent successfully
ReadyMail[smtp][20] Stop the TCPsession...

Another session:

Connecting to Wi-Fi........................
Connected with IP: 192.168.1.208

ReadyMail, version 0.3.6
ReadyMail[smtp][1] Connecting to "webreus.email" via port 587...
ReadyMail[smtp][2] Sending greeting...
ReadyMail[smtp][3] Starting TLS...
ReadyMail[smtp][3] Performing TLS handshake...
ReadyMail[smtp][3] TLS handshake done
ReadyMail[smtp][2] Sending greeting...
ReadyMail[smtp][2] Service is ready
ReadyMail[smtp][5] Authenticating...

Another session:

Connected with IP: 192.168.1.208

ReadyMail, version 0.3.6
ReadyMail[smtp][1] Connecting to "webreus.email" via port 587...
ReadyMail[smtp][2] Sending greeting...
ReadyMail[smtp][3] Starting TLS...
ReadyMail[smtp][3] Performing TLS handshake...
ReadyMail[smtp][3] TLS handshake done
ReadyMail[smtp][2] Sending greeting...
ReadyMail[smtp][2] Service is ready
ReadyMail[smtp][5] Authenticating...
ReadyMail[smtp][5] The client is authenticated successfully
ReadyMail[smtp][11] Sending Email...
ReadyMail[smtp][11] Sending envelope...
ReadyMail[smtp][12] Sending headers...
ReadyMail[smtp][14] Sending multipart content (alternative)...
ReadyMail[smtp][14] Sending text/plain body...
ReadyMail[smtp][14] Sending text/html body...type or paste code here

Another session:

Connecting to Wi-Fi...................
Connected with IP: 192.168.1.208

ReadyMail, version 0.3.6
ReadyMail[smtp][1] Connecting to "webreus.email" via port 587...
ReadyMail[smtp][2] Sending greeting...
ReadyMail[smtp][3] Starting TLS...
ReadyMail[smtp][3] Performing TLS handshake...
ReadyMail[smtp][3] TLS handshake done
ReadyMail[smtp][2] Sending greeting...
ReadyMail[smtp][2] Service is ready
ReadyMail[smtp][5] Authenticating...
ReadyMail[smtp][5] The client is authenticated successfully
ReadyMail[smtp][11] Sending Email...
ReadyMail[smtp][11] Sending envelope...
ReadyMail[smtp][12] Sending headers...
ReadyMail[smtp][14] Sending multipart content (alternative)...
ReadyMail[smtp][14] Sending text/plain body...
ReadyMail[smtp][14] Sending text/html body...

The sketch used is the same as used in the example sketch from ReadyMail.h library examples, except that I do not use the Networks.h library, and I also only use port 587 (TLS):

#include <Arduino.h>
// #include "Networks.h"
// #include <WiFiClient.h>
#include <ESP8266WiFi.h>

#define ENABLE_SMTP
#define ENABLE_DEBUG
#define READYMAIL_DEBUG_PORT Serial
#define USE_ESP_SSLCLIENT

#if defined(USE_ESP_SSLCLIENT)
#include <ESP_SSLClient.h>
#else
#include <NetworkClientSecure.h>
#endif


#if defined(USE_ESP_SSLCLIENT)
#define READYCLIENT_SSL_CLIENT ESP_SSLClient
#define READYCLIENT_TYPE_1 // TYPE 1 when using ESP_SSLClient
#else
#define READYCLIENT_SSL_CLIENT NetworkClientSecure
#define READYCLIENT_TYPE_2 // TYPE 2 when using NetworkClientSecure
#endif

#include <ReadyMail.h>

#define SMTP_HOST "____"
#define AUTHOR_EMAIL "____"
#define AUTHOR_PASSWORD "____"
#define RECIPIENT_EMAIL "____"

#define WIFI_SSID "____"
#define WIFI_PASSWORD "____"


#if defined(USE_ESP_SSLCLIENT)
WiFiClient basic_client;
ESP_SSLClient ssl_client;
#else
NetworkClientSecure ssl_client;
#endif

ReadyClient rClient(ssl_client);
SMTPClient smtp(rClient);

// For more information, see http://bit.ly/474niML
void smtpCb(SMTPStatus status)
{
  if (status.progress.available)
    ReadyMail.printf("ReadyMail[smtp][%d] Uploading file %s, %d %% completed\n", status.state,
                     status.progress.filename.c_str(), status.progress.value);
  else
    ReadyMail.printf("ReadyMail[smtp][%d]%s\n", status.state, status.text.c_str());
}

void sendEmail(int port)
{
  smtp.connect(SMTP_HOST, port, smtpCb);
  if (!smtp.isConnected())
    return;

  smtp.authenticate(AUTHOR_EMAIL, AUTHOR_PASSWORD, readymail_auth_password);
  if (!smtp.isAuthenticated())
    return;

  SMTPMessage msg;
  msg.headers.add(rfc822_subject, "ReadyMail test via port " + String(port));
  msg.headers.add(rfc822_from, "ReadyMail <" + String(AUTHOR_EMAIL) + ">");
  msg.headers.add(rfc822_to, "User <" + String(RECIPIENT_EMAIL) + ">");

  String bodyText = "Hello test.";
  msg.text.body(bodyText);
  msg.html.body("<html><body><div style=\"color:#cc0066;\">" + bodyText + "</div></body></html>");
  msg.timestamp = 1746013620;
  smtp.send(msg);
  smtp.stop();  // terminate connection https://forum.arduino.cc/t/readymail-h-example-autoclient-ino-error-sending-starttls-command/1409355/3
  delay(10);
}

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

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();

#if defined(USE_ESP_SSLCLIENT)
  ssl_client.setClient(&basic_client);
#endif

  // If server SSL certificate verification was ignored for this SSL Client.
  // To verify root CA or server SSL cerificate,
  // please consult SSL Client documentation.
  ssl_client.setInsecure();

  Serial.println("ReadyMail, version " + String(READYMAIL_VERSION));

//  rClient.addPort(465, readymail_protocol_ssl);
  rClient.addPort(587, readymail_protocol_tls);
//  rClient.addPort(25, readymail_protocol_plain_text);

//  sendEmail(465); // SSL

  sendEmail(587); // STARTTLS

  // If your server supports this protocol.
//   sendEmail(25); // Plain Text
}

void loop()
{
}

Many thanks in advance for your help,
Erik

Comparing the four runs posted, #3 and #4 are the same -- discounting the "type or paste code here" typo in #3: you don't get the final "The Email is sent successfully" in stage 14. In #2, it's stuck authenticating in stage 5

Note that in your sketch, sendEmail is the last call in setup, and the loop is empty. The end of sendEmail is send, stop, and finally delay.

That delay seems pointless: nothing happens after, anyway. The signature for send is

bool send(SMTPMessage &message, const String &notify = "", bool await = true)

so it waits by default, and is blocking. What's not clear is whether send ever returns (to then execute stop). It also returns a bool. So try changing that up a little

  bool result = smtp.send(msg);
  Serial.print("send result: ");
  Serial.println(result);
  smtp.stop();

Note whether that is taking an abnormal amount of time.

there is a newer version of the ReadyMail library: 0.4.2

try that and see if there's any improvement

by the way, what device are you running that code on?

Blockquote

@kenb4 Hi and thanks for your elaborate reply.

But I do not understand where you find that 'bool' statement in my posted sketch?

And what code should I replace with the code you proposed:

bool result = smtp.send(msg);
  Serial.print("send result: ");
  Serial.println(result);
  smtp.stop();

Well observed, I now updated the ReadyMail.h to the latest version. A few tests this morning so far show no emailing issues.

I also contacted my webhosting service, asking them if they have some sort of 'denial-of-service' implemented, and if so to dial back these settings to last year's setting for my domain.
In the past year I never had this email messaging issue. But when restarting my controller a few days ago (after a winter's break) this whole issue popped up.

This is on an ESP8266, and I know this controller requires some particular configuration:
MMU: "16kB cache + 48kB IRAM and 2nd heap (shared)".
Anyway, the whole of last year I had no emailing issues with my code... but indeed the update of the library may have helped, further testing required.

That bool is not in your sketch; it's in the source code of the function you're calling. In the IDE, the function signature is shown if you hover over it, or right-click and choose Go to Definition. It works as long as the IDE can figure out "what you meant": i.e. does the code compile successfully.

As for my suggestion, replace this part of your sketch

And since a bool just gets promoted to one or zero to print, this is a little better

  bool result = smtp.send(msg);
  Serial.print("send result: ");
  Serial.println(result ? "might have worked" : "definitely failed");
  smtp.stop();

That worked, and the email was sent succesfully. Thanks!!

Although I do not understand how

smtp.send(msg);
  smtp.stop();  

can be replaced by this below and function well:

 bool result = smtp.send(msg);
  Serial.print("send result: ");
  Serial.println(result ? "might have worked" : "definitely failed");
  smtp.stop();

It's adding a little bit of generally safe stuff in the middle. The last statement is the same. In the middle

  • instead of ignoring the return value of send, it assigns it to a local variable. This is safe unless you run out of stack space. A bool is a single byte, although it would be aligned on the stack, so it may occupy a little more space.
  • Then there are two Serial.print calls; also safe. They print hard-coded strings.
    • All three are already present in memory if the sketch compiled and uploaded successfully.
    • The second picks one hard-coded string or another, a little bit of executable logic
    • The println then tacks on "\r\n"

The difference between not working and now working could be updating the version; but you can keep this additional code, which would help diagnose things if they stop working again.

@ken4b: :heart:

Still not solved: even with ReadyMail.h latest version (0.4.2) smtp email server does not get authenticated.
When testing my email server settings on SMTP Test Tool then authentication and email test sending works well and gets sent right away;

Connected to smtp://webreus.email:587/?starttls=always
<< 220 mailnode8.webreus.email ESMTP Postfix
>> EHLO [172.31.11.248]
<< 250-mailnode8.webreus.email
<< 250-PIPELINING
<< 250-SIZE 104857600
<< 250-VRFY
<< 250-ETRN
<< 250-STARTTLS
<< 250-ENHANCEDSTATUSCODES
<< 250-8BITMIME
<< 250 DSN
>> STARTTLS
<< 220 2.0.0 Ready to start TLS
>> EHLO [x.x.x.x]
<< 250-mailnode8.webreus.email
<< 250-PIPELINING
<< 250-SIZE 104857600
<< 250-VRFY
<< 250-ETRN
<< 250-AUTH PLAIN LOGIN
<< 250-AUTH=PLAIN LOGIN
<< 250-ENHANCEDSTATUSCODES
<< 250-8BITMIME
<< 250 DSN
>> AUTH PLAIN xxxx
<< 235 2.7.0 Authentication successful
>> MAIL FROM:<erik@xxx.yy> SIZE=550
>> RCPT TO:<e.xxx@gmail.com>
<< 250 2.1.0 Ok
<< 250 2.1.5 Ok
>> DATA
<< 354 End data with <CR><LF>.<CR><LF>
>> From: erik@xxx.yy
>> Date: Wed, 27 May 2026 12:55:50 퍍
>> Subject: SMTP test from webreus.email
>> Message-Id: <BAIIOZ8HDTU4.DODEM27SGL5Z1@WIN-AUIR3RRGP88>
>> To: e.xxx@gmail.com
>> MIME-Version: 1.0
>> Content-Type: multipart/alternative; boundary="=-aQWln3OmmRdKbHmJhat3iA=="
>>
>> --=-aQWln3OmmRdKbHmJhat3iA==
>> Content-Type: text/plain; charset=utf-8
>>
>> Test message
>> --=-aQWln3OmmRdKbHmJhat3iA==
>> Content-Type: text/html; charset=utf-8
>> Content-Id: <BAIIOZ8HDTU4.QR3BJM0WCDZ@WIN-AUIR3RRGP88>
>>
>> <b>Test message</b>
>> --=-aQWln3OmmRdKbHmJhat3iA==--
>> .
<< 250 2.0.0 Ok: queued as CA2B410262C6 

When using the same correct credentials in the example sketch from ReadyMail (see sketch in my OP) the I get (at best) this output:

ReadyMail, version 0.4.2
ReadyMail[smtp][1] Connecting to "webreus.email" via port 587...
ReadyMail[smtp][2] Sending greeting...
ReadyMail[smtp][2] Sending greeting...
ReadyMail[smtp][2][-7] sendGreeting(): Send data failed

So, for some reason, this example sketch from ReadyMail does not succeed in sending emil, where a smtp server test (SMTP Test Tool), using the same credentials, does work.
The example sketch (posted in OP) had been adapted to @kenb4 suggestion in his post #4

Any ideas or suggestions?

EDIT: this is with an ESP8266 set up for

MMU: "16kB cache + 48kB IRAM and 2nd heap (shared)".

at GitHub - mobizt/ReadyMail: Fast, lightweight, and asynchronous ready-to-use email client library for Arduino. · GitHub

it says:

Known Issues

  1. ESP8266 requires buffer tuning via setBufferSizes()
  2. ESP32 v3.x may hang on setPlainStart() in plain mode
  3. Some devices may fail TLS handshake due to memory limits

SMTP Server Rejection and Spam Prevention

  1. Provide a valid EHLO/HELO hostname or IP
  2. Set the Date header using msg.timestamp = time(nullptr);
  3. Use \r\n (CRLF) line breaks instead of \n (LF)
  4. Sync time using configTime() or WiFi.getTime()

I would try the example from github that uses WiFiClientSecure rather than NetworkClientSecure

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>

#define ENABLE_SMTP
#define ENABLE_DEBUG
#include <ReadyMail.h>

WiFiClientSecure ssl_client;
SMTPClient smtp(ssl_client);

void setup() {
  Serial.begin(115200);
  WiFi.begin("YOUR_SSID", "YOUR_PASSWORD");
  while (WiFi.status() != WL_CONNECTED) delay(500);

  ssl_client.setInsecure();

  auto statusCallback = [](SMTPStatus status) {
    Serial.println(status.text);
  };

  smtp.connect("smtp.example.com", 465, statusCallback);

  if (smtp.isConnected()) {
    smtp.authenticate("user@example.com", "password", readymail_auth_password);

    SMTPMessage msg;
    msg.headers.add(rfc822_from, "ReadyMail <user@example.com>");
    msg.headers.add(rfc822_to, "Recipient <recipient@example.com>");
    msg.headers.add(rfc822_subject, "Hello from ReadyMail");
    msg.text.body("This is a plain text message.");
    msg.html.body("<html><body><h1>Hello!</h1></body></html>");

    configTime(0, 0, "pool.ntp.org");
    while (time(nullptr) < 100000) delay(100);
    msg.timestamp = time(nullptr);

    smtp.send(msg);
  }
}

void loop() {}

My code uses ESP_SSLClient.h, not NetworkClientSecure.h
Please see

#define USE_ESP_SSLCLIENT

#if defined(USE_ESP_SSLCLIENT)
#include <ESP_SSLClient.h>
#else
#include <NetworkClientSecure.h>
#endif

ESP8266 buffer size, per recommendation by @Mobizt I added:

  ssl_client.setBufferSizes(1024, 1024);  // https://github.com/mobizt/ReadyMail/discussions/12#discussioncomment-14573152; since disappeared
  Serial.println("ReadyMail, version " + String(READYMAIL_VERSION));
  rClient.addPort(587, readymail_protocol_tls);
  configTime(0, 0, "pool.ntp.org");
  while (time(nullptr) < 100000) delay(100);

What remains a mystery to me is that last year all worked well, but restarting code after last winter's season (controller not in use in winter) it does not, apart intermittently during last week's trials (please see comments in this thread up to post #5).

The example code referred to by @time_document_3108 uses SSL (port 465), not TLS (as required by my email server webreus.email).

My additions were for failing near the end, at stage 14. Your OP also has a failure at stage 5. All four of those show it going from stage 2 to stage 3, and then back to stage 2; successful or not in the end

"Sending greeting..." in stage 2 happens twice. Your current failure is missing stage 3 entirely, which are those three TLS parts, and dies at stage 2 with an actual message -- as opposed to just hanging like before (right?)

In the SMTP Test output, the corresponding sequence is EHLO, STARTTLS, and EHLO again. That's Extended HelLO: "what can you do?". The first one says several things including STARTTLS. So the mail client will try that, do EHLO again and now it's missing from the list since it is active.

(AUTH PLAIN sends your credentials encoded, but not encrypted -- looks like noise, but easily reversed. If that output is unaltered, you should consider changing your password, now that it has been posted on a public forum.)

The error message is apparently from

The __func__ matches and TCP_CLIENT_ERROR_SEND_DATA is -7. So the error is not at the SMTP protocol level, but at the "sending bytes" TCP level.

Can you try with a new replacement board?

Sure, would replacement ESP826 modules be ok?

well, it wouldn't hurt to try using NetworkClientSecure.h and changing the port from 465 to 587

unless of course you know for sure that NetworkClientSecure doesn't support your kind of TLS

@time_document_3108 yes I will give it a try this weekend.

Also going to try with some brand new ESP8266 modules; those I have in use have had their fair share of uploads; maybe RAM has gotten corrupted here or there?