Skip to content

Possible TLS tunnel corruption / reset with concurrent HTTPS CONNECT requests from Chromium / Playwright #613

Description

@khaelys

Tinyproxy version

1.11.1

Issue

We are using tinyproxy as a plain forward proxy for browser automation traffic from a GCP Cloud Run service to external HTTPS websites.

The proxy is used only for HTTPS tunneling via CONNECT. We are not doing TLS interception, TLS bumping, or certificate manipulation.

With tinyproxy, Chromium / Playwright intermittently fails while loading HTTPS resources from login.id.tim.it with TLS errors such as:

net::ERR_SSL_BAD_RECORD_MAC_ALERT
net::ERR_SSL_DECRYPT_ERROR_ALERT

The same flow works correctly when replacing tinyproxy with squid on the same VM, same port, same GCP network, same outbound IP setup, and same Playwright flow.

This suggests the issue may be related to how tinyproxy handles multiple concurrent HTTPS CONNECT tunnels from Chromium.

Environment

OS: Debian 12 on GCP Compute Engine
Client: Chromium via Playwright
Client source: GCP Cloud Run via Direct VPC Egress
Proxy mode: Plain HTTP forward proxy
HTTPS handling: CONNECT tunneling only, no TLS interception
Proxy port: 8888

Tinyproxy configuration tested

Initial minimal config:

Port 8888
Listen 0.0.0.0
Timeout 600

Allow 127.0.0.1
Allow xx.xx.xx.xx/24
Allow yy.yy.yy.yy/26

DisableViaHeader Yes
MaxClients 100

We also tested a more explicit/tuned configuration:

User tinyproxy
Group tinyproxy

Port 8888
Listen 0.0.0.0

Timeout 120

Allow 127.0.0.1
Allow xx.xx.xx.xx/24
Allow yy.yy.yy.yy/26

ConnectPort 443

MaxClients 500
StartServers 20
MinSpareServers 20
MaxSpareServers 100
MaxRequestsPerChild 0

DisableViaHeader Yes
XTinyproxy No

Syslog On
LogLevel Connect

The failure still happens with the tuned configuration.

Relevant logs

During the failing Playwright flow, tinyproxy successfully establishes the HTTPS tunnels:

May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Request (file descriptor 9): CONNECT login.id.tim.it:443 HTTP/1.1
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Established connection to host "login.id.tim.it" using file descriptor 10.

Then Chromium opens multiple parallel CONNECT tunnels to the same host:

May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Connect (file descriptor 11): 10.10.1.20
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Connect (file descriptor 13): 10.10.1.20
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Request (file descriptor 13): CONNECT login.id.tim.it:443 HTTP/1.1
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Connect (file descriptor 12): 10.10.1.20
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Connect (file descriptor 14): 10.10.1.20
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Request (file descriptor 12): CONNECT login.id.tim.it:443 HTTP/1.1
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Request (file descriptor 14): CONNECT login.id.tim.it:443 HTTP/1.1
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Request (file descriptor 11): CONNECT login.id.tim.it:443 HTTP/1.1

The tunnels are established:

May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Established connection to host "login.id.tim.it" using file descriptor 20.
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Established connection to host "login.id.tim.it" using file descriptor 17.
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Established connection to host "login.id.tim.it" using file descriptor 18.
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Established connection to host "login.id.tim.it" using file descriptor 19.
May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: Established connection to host "login.id.tim.it" using file descriptor 16.

Then tinyproxy logs a reset:

May 20 14:04:50 proxy-vm-b-0 tinyproxy[729578]: read_buffer: read() failed on fd 19: Connection reset by peer

On the Playwright/Chromium side, some HTTPS resources fail with:

net::ERR_SSL_BAD_RECORD_MAC_ALERT
net::ERR_SSL_DECRYPT_ERROR_ALERT

Comparison with Squid

Replacing tinyproxy with Squid on the same VM setup fixes the issue.

Squid config used:

http_port 0.0.0.0:8888

acl vpc_clients src 127.0.0.1/32
acl vpc_clients src xx.xx.xx.xx/24
acl vpc_clients src yy.yy.yy.yy/26

acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443
acl CONNECT method CONNECT

http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow vpc_clients
http_access deny all

via off
forwarded_for delete

cache deny all

connect_timeout 30 seconds
request_timeout 5 minutes
read_timeout 10 minutes

With Squid, the same Playwright trace completes successfully and the previously failing JS resources from login.id.tim.it return HTTP 200.

Expected behavior

tinyproxy should tunnel HTTPS traffic via CONNECT without modifying or corrupting the TLS stream, even when Chromium opens multiple parallel HTTPS tunnels to the same host.

Actual behavior

tinyproxy establishes the CONNECT tunnels, but Chromium later reports TLS-level errors on some resources:

net::ERR_SSL_BAD_RECORD_MAC_ALERT
net::ERR_SSL_DECRYPT_ERROR_ALERT

The issue appears during a burst of concurrent CONNECT requests to the same HTTPS host.

Reproduction notes

The issue is most reliably reproduced through Chromium/Playwright, likely because it opens several concurrent TLS tunnels and fetches multiple JS/static resources in parallel.

Let me know if the playwright trace could help.

Question

Is this a known limitation or bug in tinyproxy’s handling of concurrent HTTPS CONNECT tunnels?

Are there additional debug logs, compile flags, or runtime options that would help determine whether the TLS stream is being truncated, reset, or otherwise mishandled by tinyproxy?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions