MQTT-TLS could use Amazon IoT


My apologies - enableTls returns an int but connect returns a bool. So you seeing a 0 means that it is in fact unable to connect at the connection call. If enableTls is returning 0 before this (aka succeeding), it means that you likely have a permissions problem.

You can get the error code for the connection attempt by enabling debug output in MQTT-TLS.h:

make sure debug_tls is defined as below (just copy paste this below the section where it currently is defined.

#define debug_tls( fmt, ... ) \
    Serial.printf(fmt, ##__VA_ARGS__)

This will give debug output from the ssl handshake result and a few other things. I don’t want to take over this thread so feel free to PM me the result and we can follow up on this thread once we’ve figured it all out.


Thanks very much - I ended up going with Google IoT as required less memory from my photon !

Appreciate the help!


I’ve been banging my head trying to get something working with this for a while.

I’ve temporarily set up a policy that has IoT Full access, attached it to the certificate, and then configured the sample code to connect and publish to an AWS MQTT channel - but it just plain doesn’t work for me. I’ve recreated certs, I’ve even swapped out every possible variation of the AWS root cert CA, still nothing happening.

I tried adding the debug_tls stuff to the MQTT-TLS.h file, but it didn’t seem to add any debug information.

The client.enableTls succeeds (but I think this just means that it checks my certs are formatted properly) but the connection itself always fails.

The device connects to the spark cloud just fine before it’s even trying to enable tls, so I know the wifi is working.

Any ideas? I assume that other people have this working? (I’m on version=0.2.20 of the mqtt-tls library, if it makes a difference)


The debug you are looking for would specifically be the results of each step of the handshake. There is always an error code somewhere, and that is usually returned by the ssl handshake.

If you aren’t seeing debug Serial print lines, you haven’t configured the debug printing properly. To make sure it’s configured, just stick this at the top of MQTT-TLS.cpp:

#define debug_tls( fmt, ... ) \
    Serial.printf(fmt, __VA_ARGS__)

Or just do a find and replace for debug_tls for Serial.printf.

The code that says "handshake done, ret = " will be the code that contains the error in most cases. The step it fails on and the way it fails should tell you what is going wrong.

Most of the time the error is on the configuration and permissions side. Usually worth making sure you have an AWS Thing set up with a name equal to the client id you are using to connect. While not strictly necessary, this may help rule out some possible causes. Also make sure that the certificate itself is in the “Active” state, and attached to that Thing.

I always use Amazon Root CA 1 (RSA 2048 bit key) and it works fine for me. Double check that your endpoint domain and port (8883) are correctly configured.

Are you going through a firewall? Port 8883 may not be opened in the firewall security policy as it isn’t commonly used for normal web traffic.


You can use mqtt.fx ( running on your mac/pc to check your device credentials - just to make sure you didnt make copy/paste errors.

Additionally, the TLS library is very RAM hungry when it starts up; running on a P1 with 10K fails to make the connection to AWS but having > 14K RAM free works fine (with my config, may be different for you). That isn’t to say that the TLS lib needs 10K+ permanently; it needs this mostly during startup. So make sure that connecting to AWS-iot is one of the first things you do during startup and your own app RAM requirements are delayed till that connection is made successfully. Secondly, that if the AWS-iot connection breaks for some reason later on, make enough RAM available before reconnecting. In some cases it is easier to reset your device then to build all this dynamic alloc/dealloc behavior.


Thanks for all the suggestions, in the end I got the Argon to work with its additional memory. I found also that you have to use the legacy CA from AWS, as the other CA certs won’t working for me.


The legacy Root CA (VeriSign Class 3 Public Primary G5 root CA certificate) did NOT work for me. If I use the Amazon Root CA 1 (RSA 2048 bit key) it works fine (tested on region eu-central-1). Root CAs can be found here:


The Amazon Root CA 1 cert is what works for me as well in US-East-2. I wonder if the CA cert required depends on the AWS region.


Shouldnt be; i have connected to east1 and 2 as well as west 1 and 2 with the same cert


I follow the example above then compile and flash to Argon 1.3.0-rc.1 without error but when I publish message “RED” with “inTopic/message” in AWS, it does not work (LED color not change).
Does anyone know how to verify it? Thanks!

The certificate I use:
CELINT_KEY_CRT_PEM = AWS_Argon.cert.pem
CELINT_KEY_PEM = AWS_Argon.private.key



I’m not convinced that library supports Gen3 - you may need to ask the contributor @hirotakaster


I’m using MQTT-TLS successfully on Boron LTE. The certificates can be tricky to get set up. Mainly the Root CA, since Amazon publishes multiple certificates, but only one typically works.


Hi guys,

mbedTLS in MQTT support RSA 2048/4096, ECC 256/384(but enable ECC options in config.h).
If some trouble with AWS Root CA, I think it’s better that trying to check the AWS IoT gateway with other MQTT commands(like a mosquitto_pub/sub) for RootCA compatibility.



Thanks for telling us about it.


Once I used the rootCA issued to me by AWS for use in my region, the sample code for the project worked perfectly. Perhaps remove the root CA from the sample as for some of us it prevents the example from working.

Also, worth pointing out that you should check the certificate policy if you are having issues with connecting, or publishing and subscribing to topics. The client ID you specify needs to be allowed by policy to do the things you are trying to do.


Hey folks,

I’ve been working on this one and sort of slamming my head against the mbedtls portion.

I wind up getting a hex value of -2180 (dec -8576) using @justicefreed_amper 's debug technique on an Argon. I double checked and reentered my certs.

#define AMAZON_IOT_ROOT_CA_PEM                                              \
"-----BEGIN CERTIFICATE-----\r\n"                                           \
"MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\r\n"       \
"ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\r\n"       \
"9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\r\n"       \
"IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\r\n"       \
"VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\r\n"       \
"93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\r\n"       \
"A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\r\n"       \
"U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\r\n"       \
"N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\r\n"       \
"o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\r\n"       \
"5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\r\n"       \
"rqXRfboQnoZsG4q5WTP468SQvvG5\r\n"                                           \
const char amazonIoTRootCaPem[] = AMAZON_IOT_ROOT_CA_PEM;

#define CELINT_KEY_CRT_PEM                                              \
"-----BEGIN PUBLIC KEY-----\r\n"                                        \
"YQ0ziIAjehEoHhQXnOPoZjqPvpjNqP5mVkhnKJUW3c2sazWLYxDqdkpLotGT\r\n"       \
"-----END PUBLIC KEY-----"
const char clientKeyCrtPem[] = CELINT_KEY_CRT_PEM;

#define CELINT_KEY_PEM                                                  \
"-----BEGIN RSA PRIVATE KEY-----\r\n"                                   \
"MIIEowIBAAKCAQEAyj3y3xuenIfsu23wvNgS5i8AMVCAdA9rvYGSColgR5zDD6Ht\r\n"   \
"ETVIHWxuTzeM52Fxm3j0t4wIH1tnpy2+dumAKTrDk7d1BIHTHQZa\r\n"               \
"-----END RSA PRIVATE KEY----- "                                 
const char clientKeyPem[] = CELINT_KEY_PEM;

if ( (ret = client.enableTls(amazonIoTRootCaPem, strlen(amazonIoTRootCaPem)+1,
                             clientKeyCrtPem, strlen(clientKeyCrtPem)+1,
                             clientKeyPem, strlen(clientKeyPem)+1)) < 0) 

I did a quick openssl connect check so I know the certs are good. Any ideas here?


Hey. That error is MBEDTLS_ERR_X509_INVALID_FORMAT, with the comment:

The CRT/CRL/CSR format is invalid, e.g. different type expected.

I can confirm that your AMAZON_IOT_ROOT_CA_PEM is correct and consistent with mine.

I noticed that at the end of your RSA Private Key “CELINT_KEY_PEM”, there is an extra space. Delete that space though it shouldn’t be your issue here.

Your clientKeyCrtPem is wrong. You have the public key, put you actually need a PEM formatted certificate. These start with:

"-----BEGIN CERTIFICATE-----\r\n"  \

This is likely the source of your problem. You appear to have downloaded the public key from AWS instead of the certificate. If you don’t have a copy, create a new certificate and download again, this time using the certificate as per this picture:

Also consider fixing the typo of “CELINT_KEY…” instead of “CLIENT_KEY…”. It’s not the source of the problem but will prevent future confusion (I know it’s in the sample code).


Yup, that was it! Its funny, that was just leftover from another test/example I was doing. I actually was using my cert there - just didn’t change the header!

Thanks for the help!


Hi there,

I’ve got a an Argon running the example code with a few issues.

From my serial monitor output:

handshake done, ret = 0
tls connected
MQTT connected.
client connected

And then “mqtt disconnected” at some later point after a bunch of “netWrite!!” lines. (what are those?)

Is this a function of my code? I don’t have control of the AWS IoT account, and I cannot see anything related to rules, etc.

What triggers “mqtt disconnected”? Is that passed back from the server? or do I need to take some action to keep the connection open?



example code?

You are going to need to post some code or provide more detail - my crystal ball is cloudy today… Serial output is not on by default - so we need to know what has enabled it and then can perhaps get to the bottom of the issue?