Summary
The hardcoded m_iobuf[2048] in src/SSLClient.h (line ~469) is too small to hold a full-size (16 KB) TLS record, so any bulk HTTPS download aborts partway through with BR_ERR_TOO_LARGE. Small requests (e.g. a short POST) work fine, which makes the failure look intermittent and confusing. Changing the buffer to BR_SSL_BUFSIZE_MONO fixes it completely, but requires editing library source. This is a request to make the buffer size configurable (constructor or template arg) instead of a source edit.
Environment
- Library: SSLClient, latest
master
- MCU: ESP32 (Arduino-ESP32 core)
- Transport:
EthernetClient from EthernetENC (ENC28J60)
- Server: standard HTTPS (Apache/nginx), file ~1 MB,
Content-Length present, HTTP/1.1 200 OK
What works vs what fails
- ✅ TLS handshake, trust-anchor cert verification, and small request/response (short POST) — all fine.
- ❌ Streaming a ~1 MB body over HTTPS aborts at ~43,000 bytes every time.
Error output
[DL] status: HTTP/1.1 200 OK
[DL] size: 1074.36 KB
[DL] 40.5 / 1074.4 KB (4%)
(SSLClient)(SSL_ERROR)(available): Cannot operate on a closed SSL connection.
(SSLClient)(SSL_ERROR)(m_print_br_error): Incoming record is too large to be processed, or buffer is too small for the handshake message to send.
Root cause
src/SSLClient.h (~line 469):
unsigned char m_iobuf[2048];
TLS records can be up to 16 KB. The first max-size record after the headers overflows the 2048-byte buffer, so BearSSL returns BR_ERR_TOO_LARGE. It's also below the ~8000-byte minimum the code's own comment recommends.
The duplex-selection logic in src/SSLClient.cpp already keys off this size, so a mono-sized buffer is handled correctly by the engine:
constexpr auto duplex = sizeof m_iobuf <= BR_SSL_BUFSIZE_MONO ? 0 : 1;
Fix that works
Changing the declaration to:
unsigned char m_iobuf[BR_SSL_BUFSIZE_MONO]; // 16709 bytes
makes the download complete fully:
[DL] DONE 1100144 B in 26.56 s = 331.4 kbit/s (40.4 KB/s)
[DL] full file received
RAM cost: ~14 KB extra — negligible on ESP32, but understandably not desirable as a global default for RAM-constrained boards (SAMD, AVR).
Requested change
Rather than forcing users to patch library source, expose the buffer size — e.g. a template parameter or constructor argument, defaulting to the current 2048 to preserve existing behavior — so applications that need bulk downloads can opt into a full-record buffer.
Minimal repro
SSLClient client(base_client, TAs, (size_t)TAs_NUM, RAND_PIN);
// GET a ~1 MB file over :443, stream the body in a read loop → aborts ~43 KB
Summary
The hardcoded
m_iobuf[2048]insrc/SSLClient.h(line ~469) is too small to hold a full-size (16 KB) TLS record, so any bulk HTTPS download aborts partway through withBR_ERR_TOO_LARGE. Small requests (e.g. a short POST) work fine, which makes the failure look intermittent and confusing. Changing the buffer toBR_SSL_BUFSIZE_MONOfixes it completely, but requires editing library source. This is a request to make the buffer size configurable (constructor or template arg) instead of a source edit.Environment
masterEthernetClientfrom EthernetENC (ENC28J60)Content-Lengthpresent,HTTP/1.1 200 OKWhat works vs what fails
Error output
Root cause
src/SSLClient.h(~line 469):TLS records can be up to 16 KB. The first max-size record after the headers overflows the 2048-byte buffer, so BearSSL returns
BR_ERR_TOO_LARGE. It's also below the ~8000-byte minimum the code's own comment recommends.The duplex-selection logic in
src/SSLClient.cppalready keys off this size, so a mono-sized buffer is handled correctly by the engine:Fix that works
Changing the declaration to:
makes the download complete fully:
RAM cost: ~14 KB extra — negligible on ESP32, but understandably not desirable as a global default for RAM-constrained boards (SAMD, AVR).
Requested change
Rather than forcing users to patch library source, expose the buffer size — e.g. a template parameter or constructor argument, defaulting to the current 2048 to preserve existing behavior — so applications that need bulk downloads can opt into a full-record buffer.
Minimal repro