ESP32 cannot establish TLS/SSL connection to Fly.io - anyone found a workaround?

Hey folks,

I’ve been building a BLE visualization project where an ESP32 scans for Bluetooth devices and sends the data to a Node.js server hosted on Fly.io. The server then broadcasts to browser clients via Socket.IO. The browser connections work perfectly - it’s just the ESP32 → Fly.io leg that’s failing.

The Setup:

  • ESP32 (Arduino) scanning BLE devices

  • Node.js + Express + Socket.IO server on Fly.io

  • Browser visualizer connecting via Socket.IO (works great)

  • ESP32 attempting to connect via WebSocket over TLS (fails)

What I’ve tried:

  1. WebSocket with SSL using WebSocketsClient library:
webSocket.beginSSL("data.MYURL.com", 443, "/esp32");

Result: Silently fails, no connection, no error events fired.

  1. WebSocket with CA certificate:
webSocket.beginSslWithCA(host, port, path, NULL, "");

Result: Same silent failure.

  1. Basic HTTPS test to isolate the issue:
HTTPClient http;
http.begin("https://data.MYURL.com/esp32");
int code = http.GET();
Serial.printf("HTTPS test result: %d\n", code);

Result: Returns -1 - the ESP32 cannot establish ANY TLS connection to Fly.io.

  1. Verified Fly.io config has h2_backend = false to force HTTP/1.1:
[http_service.http_options]
  h2_backend = false

  1. Tested WebSocket upgrade works from curl with HTTP/1.1:
curl -i -N --http1.1 \
  -H "Connection: Upgrade" \
  -H "Upgrade: websocket" \
  -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
  -H "Sec-WebSocket-Version: 13" \
  https://data.MYURL.com/esp32

Result: Returns 101 Switching Protocols - so the server-side is working correctly.

The conclusion:

The ESP32’s embedded TLS stack (mbedTLS) cannot complete a TLS handshake with Fly.io’s edge proxy. Browser clients and curl work fine because they use modern, full-featured TLS implementations. The ESP32’s lightweight embedded crypto library seems incompatible with something in Fly’s TLS configuration (cipher suites? ALPN negotiation? SNI handling?).

My workaround:

I’m implementing an HTTP POST /ingest endpoint as a fallback. The ESP32 will POST batched device data every 500ms instead of using WebSocket. Not as elegant, but it should work since even basic HTTPS fails.

Questions for the community:

  1. Has anyone successfully connected an ESP32 (or similar microcontroller) directly to a Fly.io app over TLS/WSS?

  2. Is there a specific TLS configuration on Fly’s edge that could be tweaked to support embedded clients?

  3. Are there any Fly.io settings I’m missing that might help with mbedTLS compatibility?

Any insights appreciated. Happy to share more details about my setup if it helps debug this.

Environment:

  • ESP32 Dev Module

  • Arduino framework

  • WebSocketsClient library

  • Fly.io with Node.js 18

just to confirm, are you able to establish TLS connections to sites not hosted on Fly, such as example.com, and if so do other sites with certificates from letsencrypt work (such as letsencrypt.org)?

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.