GsmSSLWebClient example fails with "HTTP/1.1 301 Moved Permanently"

The problem.

  1. I had a project working like a charm, which used to put data into a mongodb atlas database using a webhook.
  • I developed it from arduino create.
  • I am using an MKR GSM 1400 board
  1. The project suddenly stopped working, giving me a “301 Moved Permanently”
  2. I decided to use the GsmSSLWebClient example to troubleshoot, and got the same error message.
  3. I used the exact same code as the example, just changing the values for my GSM sim card. (will add it in a subsequent comment since I exceeded the maximum allowed message length.
  4. The full output when including “MODEM.debug();” is below:
Starting Arduino web client.
TAT

OK
AT+IPR=921600

OK
AT

OK
AT+UPSV=3

OK
AT+CPIN?

ERROR
AT+CPIN?

+CPIN: READY

OK
AT+CMGF=1

OK
AT+UDCONF=1,1

OK
AT+CTZU=1

OK
AT+UDTMFD=1,2

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK

+UMWI: 0,1

+UMWI: 0,2

+UMWI: 0,3

+UMWI: 0,4
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,0

OK
AT+CREG?

+CREG: 0,5

OK
AT+UCALLSTAT=1

OK
AT+CGATT=1

OK
AT+UPSD=0,1,"hologram"

OK
AT+UPSD=0,6,3

OK
AT+UPSD=0,2,""

OK
AT+UPSD=0,3,""

OK
AT+UPSD=0,7,"0.0.0.0"

OK
AT+UPSDA=0,3

OK
AT+UPSND=0,8

+UPSND: 0,8,1

OK
connecting...
AT+USECMNG=0,0,"AddTrust_External_CA_Root",1082
>
+USECMNG: 0,0,"AddTrust_External_CA_Root","1d3554048578b03f42424dbf20730a3f"

OK
AT+USECMNG=0,0,"Baltimore_CyberTrust_Root",891
>
+USECMNG: 0,0,"Baltimore_CyberTrust_Root","acb694a59c17e0d791529bb19706a6e4"

OK
AT+USECMNG=0,0,"COMODO_RSA_Certification_Authority",1500
>
+USECMNG: 0,0,"COMODO_RSA_Certification_Authority","1b31b0714036cc143691adc43efdec18"

OK
AT+USECMNG=0,0,"DST_Root_CA_X3",846
>
+USECMNG: 0,0,"DST_Root_CA_X3","410352dc0ff7501b16f0028eba6f45c5"

OK
AT+USECMNG=0,0,"DigiCert_High_Assurance_EV_Root_CA",969
>
+USECMNG: 0,0,"DigiCert_High_Assurance_EV_Root_CA","d474de575c39b2d39c8583c5c065498a"

OK
AT+USECMNG=0,0,"Entrust_Root_Certification_Authority",1173
>
+USECMNG: 0,0,"Entrust_Root_Certification_Authority","d6a5c3ed5ddd3e00c13d87921f1d3fe4"

OK
AT+USECMNG=0,0,"Equifax_Secure_Certificate_Authority",804
>
+USECMNG: 0,0,"Equifax_Secure_Certificate_Authority","67cb9dc013248a829bb2171ed11becd4"

OK
AT+USECMNG=0,0,"GeoTrust_Global_CA",856
>
+USECMNG: 0,0,"GeoTrust_Global_CA","f775ab29fb514eb7775eff053c998ef5"

OK
AT+USECMNG=0,0,"GeoTrust_Primary_Certification_Authority_G3",1026
>
+USECMNG: 0,0,"GeoTrust_Primary_Certification_Authority_G3","b5e83436c910445848706d2e83d4b805"

OK
AT+USECMNG=0,0,"GlobalSign",958
>
+USECMNG: 0,0,"GlobalSign","9414777e3e5efd8f30bd41b0cfe7d030"

OK
AT+USECMNG=0,0,"Go_Daddy_Root_Certificate_Authority_G2",969
>
+USECMNG: 0,0,"Go_Daddy_Root_Certificate_Authority_G2","803abc22c1e6fb8d9b3b274a321b9a01"

OK
AT+USECMNG=0,0,"VeriSign_Class_3_Public_Primary_Certification_Authority_G5",1239
>
+USECMNG: 0,0,"VeriSign_Class_3_Public_Primary_Certification_Authority_G5","cb17e431673ee209fe455793f30afa1c"

OK
AT+USECMNG=2,0,"AmazonRootCA1"

ERROR
AT+USECMNG=0,0,"Starfield_Services_Root_Certificate_Authority_G2",1011
>
+USECMNG: 0,0,"Starfield_Services_Root_Certificate_Authority_G2","173574af7b611cebf4f93ce2ee40f9a2"

OK
AT+USOCR=6

+USOCR: 0

OK
AT+USOSEC=0,1,0

OK
AT+USECPRF=0,0,1

OK
AT+USOCO=0,"arduino.cc",443

OK
connected
AT+USOWR=0,4,"47455420"

+USOWR: 0,4

OK
AT+USOWR=0,14,"2F61736369696C6F676F2E747874"

+USOWR: 0,14

OK
AT+USOWR=0,9,"20485454502F312E31"

+USOWR: 0,9

OK
AT+USOWR=0,2,"0D0A"

+USOWR: 0,2

OK
AT+USOWR=0,6,"486F73743A20"

+USOWR: 0,6

OK
AT+USOWR=0,10,"61726475696E6F2E6363"

+USOWR: 0,10

OK
AT+USOWR=0,2,"0D0A"

+USOWR: 0,2

OK
AT+USOWR=0,17,"436F6E6E656374696F6E3A20636C6F7365"

+USOWR: 0,17

OK
AT+USOWR=0,2,"0D0A"

+USOWR: 0,2

OK
AT+USOWR=0,2,"0D0A"

+USOWR: 0,2

OK
AT+USORD=0,512

+USORD: 0,0,""

OK
AT+USORD=0,512

+USORD: 0,0,""

OK
AT+USORD=0,512

+USORD: 0,0,""

OK
AT+USORD=0,512

+USORD: 0,0,""

OK
AT+USORD=0,512

+USORD: 0,502,"485454502F312E3120333031204D6F766564205065726D616E656E746C790D0A5365727665723A206E67696E780D0A446174653A204D6F6E2C2030352041707220323032312030333A32393A333420474D540D0A436F6E74656E742D547970653A20746578742F68746D6C0D0A436F6E74656E742D4C656E6774683A203137380D0A436F6E6E656374696F6E3A20636C6F73650D0A4C6F636174696F6E3A2068747470733A2F2F7777772E61726475696E6F2E63632F61736369696C6F676F2E7478740D0A5374726963742D5472616E73706F72742D53656375726974793A206D61782D6167653D3530303B20696E636C756465537562446F6D61696E730D0A582D436F6E74656E742D547970652D4F7074696F6E733A206E6F736E6966660D0A582D5853532D50726F74656374696F6E3A20313B206D6F64653D626C6F636B0D0A0D0A3C68746D6C3E0D0A3C686561643E3C7469746C653E333031204D6F766564205065726D616E656E746C793C2F7469746C653E3C2F686561643E0D0A3C626F6479206267636F6C6F723D227768697465223E0D0A3C63656E7465723E3C68313E333031204D6F766564205065726D616E656E746C793C2F68313E3C2F63656E7465723E0D0A3C68723E3C63656E7465723E6E67696E783C2F63656E7465723E0D0A3C2F626F64793E0D0A3C2F68746D6C3E0D0A"

OK

+UUSORD: 0,4294967295
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 05 Apr 2021 03:29:34 GMT
Content-Type: text/html
Content-Length: 178
Connection: close
Location: https://www.arduino.cc/asciilogo.txt
Strict-Transport-Security: max-age=500; includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
AT+USORD=0,512

+USORD: 0,0,""

OK
AT+USORD=0,512

+USORD: 0,0,""

OK
AT+USOCL=0

OK

disconnecting.
  1. If I replace “GSMSSLClient client;” with “GSMClient client;”, and “int port = 443;” with “int port = 80;”, the code works fine.

Question.

  1. Any suggestion about how to make the GsmSSLWebClient example work will be highly appreciated. I hope that fising this will allow me to also figure out what happened to my project.
  2. I will be happy to provide any further required information if needed.

Thanks in advance team!

It seems like other users have reported this in the past, however unresolved.

As mentioned in step 4 in my initial post, here is the code I am using:

/*
  Web client

 This sketch connects to a website using SSL through a MKR GSM 1400 board. Specifically,
 this example downloads the URL "http://www.arduino.cc/asciilogo.txt" and
 prints it to the Serial monitor.

 Circuit:
 * MKR GSM 1400 board
 * Antenna
 * SIM card with a data plan

 created 8 Mar 2012
 by Tom Igoe
*/

// libraries
#include <MKRGSM.h>

// Please enter your sensitive data in the Secret tab or arduino_secrets.h
// PIN Number
// APN data
const char GPRS_APN[]      = SECRET_GPRS_APN;
char login[] = "<here goes my user login>";
char password[] = "<here goes my pasword>";
const char PINNUMBER[] = "<here goes my pin>";

// initialize the library instance
GSMSSLClient client;
GPRS gprs;
GSM gsmAccess;

// URL, path and port (for example: arduino.cc)
char server[] = "arduino.cc";
char path[] = "/asciilogo.txt";
int port = 443; // port 443 is the default for HTTPS

void setup() {
  
     MODEM.debug();
  
  
  // initialize serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("Starting Arduino web client.");
  // connection state
  bool connected = false;

  // After starting the modem with GSM.begin()
  // attach the shield to the GPRS network with the APN, login and password
  while (!connected) {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
        (gprs.attachGPRS(GPRS_APN, login, password) == GPRS_READY)) {
      connected = true;
    } else {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, port)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.print("GET ");
    client.print(path);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.available() && !client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    for (;;)
      ;
  }
}

I think I figured this part out. Here is how I made it...

  1. I ran "curl https://www.arduino.cc/asciilogo.txt -v", which was successful
  2. In the response, I noticed this "Connected to www.arduino.cc (104.18.29.45) port 443 (#0)".
  3. In the code, when constructing the http get, the example includes client.println(server), which was defined as "arduino.cc"
  4. If you ping "arduino.cc", you get IP 100.24.172.113, which is diferent to the IP above.
  5. However, you can obtain IP 104.18.29.45 when pinging "www.arduino.cc".
  6. With all the above, I replaced the line client.println(server) with client.println("www.arduino.cc"). That fixed it!

I think you guys should update that example to prevent newbies like me from hitting the same problem. I also help this post helps others.

I will continue troubleshooting my own project, and will raise a separate post if unsuccessful.

Thanks so much for reporting this @sergiocastrogom. It seems the URL of this file has changed since the time the example was written. I did an investigation and found the same solution as you. I thought of submitting a pull request for that fix, but it seems like there should be some better way to do this, so instead I submitted a bug report with all the information:

If anyone has advice for the best way to fix the example, I am definitely interested.

If you have problem with HTTPS or MQTTS, try the new GSM_Generic Library which has the similar GsmSSLWebClient and new GSM_MQTTS_ThingStream examples.

Thanks for the prompt reply Pert! I noticed you posted this as a bug in github, so im glad to see that feedback is welcomed :).

By the way, I raised a separate request via Github (Add a way to include more root certs to be used · Issue #132 · arduino-libraries/MKRGSM · GitHub). I hope is okay to report those there, otherwise I will be happy to raise it here.

Awesome, thanks!

I think I speak for all newbies around when saying that the best way to adopt a new library is through those awesome examples you guys write. If there is any for that new GSM_Generic_Library (particularly for HTTPS web clients), it would great to have access to it.

Thanks!