HTTP status code "-3"

Hello everyone,

I'm trying to transmit some data (Ex. Temperature readings) to ARTIK cloud using Arduino mkr 1000 and HTTP POST. This is my code:

#include <WiFi101.h>
#include <ArduinoJson.h>
#include <ArduinoHttpClient.h>

// ARTIK Cloud REST endpoint
char server[] = "api.artik.cloud";  
int port = 443; // We're using HTTPS

// Device ID tokens
String deviceToken = "1bda8a571ee64fbc92e824521745ac58";
String deviceId = "734106557a134deaadafeaf4d42b8f2a";

char ssid[] = "mySSID";
char pass[] = "myPASS";   

float temperature = 0.0;

char buf[200]; // buffer to store the JSON to be sent to the ARTIK cloud

WiFiSSLClient wifi;
HttpClient client = HttpClient(wifi, server, port);

int status = WL_IDLE_STATUS;


void setup() {

   Serial.begin(9600);
  while(!Serial); 
  while ( status != WL_CONNECTED) { // Keep trying until connected
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                  
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);
    long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  }
}
  
void loop() {
  Serial.println("loop");
  
  Serial.println("making POST request");
  String contentType = "application/json";
  String AuthorizationData = "Bearer " + deviceToken; //Device Token

  
  temperature = ((analogRead(A0) * (3300/1024)) -500 ) / 10 ; // in milliVolt
  
  int len = loadBuffer(temperature);  
  Serial.println("Sending data "+String(temperature)); 

  
  // push the data to the ARTIK Cloud
  client.beginRequest();
  client.post("/v1.1/messages"); //, contentType, buf
  client.sendHeader("Authorization", AuthorizationData);
  client.sendHeader("Content-Type", "application/json");
  client.sendHeader("Content-Length", len);
  client.endRequest();
  client.print(buf);

  // read the status code and body of the response
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  Serial.print("Status code: ");
  Serial.println(statusCode);
  
  Serial.print("Response: ");
  Serial.println(response);

  Serial.println("Wait a bit");

 
  delay(30000); // delay 5 min

}

int loadBuffer(float temp) {  
   StaticJsonBuffer<200> jsonBuffer; // reserve spot in memory

   JsonObject& root = jsonBuffer.createObject(); // create root objects
     root["sdid"] =  deviceId;  
     root["type"] = "message";

   JsonObject& dataPair = root.createNestedObject("data"); // create nested objects
     dataPair["Temperature"] = temp;  

   root.printTo(buf, sizeof(buf)); // JSON-print to buffer

   return (root.measureLength()); // also return length
 }

The libraries i'm using can be found here:
ArduinoJson
ArduinoHttpClient

At the beginning, the code was working perfectly and I was able to transmit the data to the cloud where I used to get a response of 200.

However, whenever I try to send data to the cloud now I get:
Status code: -3
Response:

I have searched online but I couldn't find a solution.

According to the ARTIK support, there is nothing wrong with their API.

I have tried to create a new account on the cloud, to change the microcontroller, and to use a different network connection so far but I can't get it to work.

Any help would be highly appreciated.

Thanks in advance,

Status -3 is timeout.
The reason is probably that you promise 'len' bytes to the server, but you end the request before sending them. The server just keeps on waiting.

Just follow the example.

Pieter

@Pieter P, Thank you for your response.

PieterP:
The reason is probably that you promise 'len' bytes to the server, but you end the request before sending them. The server just keeps on waiting.

Yes I understand, but there is a function call (loadBuffer) before the POST that returns len.

TasBas:
int len = loadBuffer(temperature);
Serial.println("Sending data "+String(temperature));

// push the data to the ARTIK Cloud
client.beginRequest();
client.post("/v1.1/messages"); //, contentType, buf
client.sendHeader("Authorization", AuthorizationData);
client.sendHeader("Content-Type", "application/json");
client.sendHeader("Content-Length", len);
client.endRequest();
client.print(buf);

In addition, according to the link you sent:

"static const int HTTP_ERROR_TIMED_OUT =-3;
// The response from the server is invalid, is it definitely an HTTP
// server?"

Does this mean there is an issue with the server of the cloud (cloud API)?

Example:

  String postData = "name=Alice&age=12";

  client.beginRequest();
  client.post("/");
  client.sendHeader("Content-Type", "application/x-www-form-urlencoded");
  client.sendHeader("Content-Length", postData.length());
  client.sendHeader("X-Custom-Header", "custom-header-value");
  client.beginBody();
  client.print(postData);
  client.endRequest();

Your code:

  client.beginRequest();
  client.post("/v1.1/messages"); //, contentType, buf
  client.sendHeader("Authorization", AuthorizationData);
  client.sendHeader("Content-Type", "application/json");
  client.sendHeader("Content-Length", len);
  client.endRequest();
  client.print(buf);

No, it is not a server problem, your code is wrong. You're sending data after you ended the request, and you don't finish the header or start the body.

Hello PieterP,

You were right. It's not a server problem and I have just received the confirmation from the cloud. I made the changes you mentioned to the code but the result is still as it was.

I tried to send an HTTP POST request using Postman and I was successfully able to send data to the cloud. With that working, I can't figure out what is the problem. It seems like the microcontroller is not able to send POST requests on port 443 but it doesn't make sense because I tried other devices as well.

Could this be an issue with the libraries i'm using, or is it a code issue?

This is my updated code based on your suggestions:

#include <WiFi101.h>
#include <ArduinoJson.h>
#include <ArduinoHttpClient.h>

// ARTIK Cloud REST endpoint
char server[] = "api.artik.cloud";  
int port = 443; // We're using HTTPS

// Device ID tokens
String deviceToken = "1bda8a571ee64fbc92e824521745ac58";
String deviceId = "734106557a134deaadafeaf4d42b8f2a";

char ssid[] = "mySSID";
char pass[] = "myPASS";   

float temperature = 0.0;

char buf[200]; // buffer to store the JSON to be sent to the ARTIK cloud

WiFiSSLClient wifi;
HttpClient client = HttpClient(wifi, server, port);

int status = WL_IDLE_STATUS;


void setup() {

   Serial.begin(9600);
  while(!Serial); 
  while ( status != WL_CONNECTED) { // Keep trying until connected
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                  
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);
    long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  }
}
  
void loop() {
  Serial.println("loop");
  
  Serial.println("making POST request");
  String contentType = "application/json";
  String AuthorizationData = "Bearer " + deviceToken; //Device Token

  
  temperature = ((analogRead(A0) * (3300/1024)) -500 ) / 10 ; // in milliVolt
  
  int len = loadBuffer(temperature);  
  Serial.println("Sending data "+String(temperature)); 

  
  // push the data to the ARTIK Cloud
  client.beginRequest();
  client.post("/v1.1/messages"); //, contentType, buf
  client.sendHeader("Authorization", AuthorizationData);
  client.sendHeader("Content-Type", "application/json");
  client.sendHeader("Content-Length", len);
  client.beginBody();
  client.print(buf);
  client.endRequest();

  // read the status code and body of the response
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  Serial.print("Status code: ");
  Serial.println(statusCode);
  
  Serial.print("Response: ");
  Serial.println(response);

  Serial.println("Wait a bit");

 
  delay(30000); // delay 5 min

}

int loadBuffer(float temp) {  
   StaticJsonBuffer<200> jsonBuffer; // reserve spot in memory

   JsonObject& root = jsonBuffer.createObject(); // create root objects
     root["sdid"] =  deviceId;  
     root["type"] = "message";

   JsonObject& dataPair = root.createNestedObject("data"); // create nested objects
     dataPair["Temperature"] = temp;  

   root.printTo(buf, sizeof(buf)); // JSON-print to buffer

   return (root.measureLength()); // also return length
 }

Read the response from the server, and check the server logs. If that doesn't work, start a TLS socket server on your computer and read the data that's sent by the Arduino.

I apologize for the late reply.

After trying multiple things to solve the issue, I tried to use the firmware updater to update the SSL certificates. Apparently, the cloud updated their certificate and this caused the issue. Once updated, the code worked perfectly as it used to.

Thank you PieterP for your help :slight_smile:

Thank you very much! I had the same issue, after updating the SSL certificate, it worked.

Best, Thorsten