XX-net/XX-Net · error · SslWrapFail

SslWrapFail

Error message

SslWrapFail

What it means

do_gae calls g.gae_proxy.proxy_handler.wrap_ssl() to wrap the socket in the fake-CA TLS layer; if that raises any exception it is converted to SslWrapFail (the original exception is discarded). This means the local TLS handshake / certificate generation failed, e.g. missing or corrupted CA cert/key files or a handshake error with the client.

Source

Thrown at code/default/smart_router/local/smart_route.py:315


def do_gae(sock, host, port, client_address, left_buf=""):
    if not g.gae_proxy:
        raise DontFakeCA()

    sock.setblocking(1)
    if left_buf:
        schema = b"http"
    else:
        leadbyte = sock.recv(1, socket.MSG_PEEK)
        if leadbyte in (b'\x80', b'\x16'):
            if host != fake_host and not g.config.enable_fake_ca:
                raise DontFakeCA()

            try:
                sock._sock = g.gae_proxy.proxy_handler.wrap_ssl(sock._sock, host, port, client_address)
            except Exception as e:
                raise SslWrapFail()

            schema = b"https"
        else:
            schema = b"http"

    sock.setblocking(1)
    xlog.debug("host:%s:%d do gae", host, port)
    req = g.gae_proxy.proxy_handler.GAEProxyHandler(sock._sock, client_address, None, xlog)
    req.parse_request()

    if req.path[0] == b'/':
        url = b'%s://%s%s' % (schema, req.headers[b'Host'], req.path)
    else:
        url = req.path

    if url in [b"http://www.twitter.com/xxnet",
                    b"https://www.twitter.com/xxnet",
                    b"http://www.deja.com/xxnet",

View on GitHub (pinned to cfa5bc17b6)

Solutions

  1. Check that the fake CA certificate and key exist and are readable; regenerate them if missing or corrupt
  2. Ensure the process has write permission to the certificate generation directory
  3. Install/trust the fake CA in the client OS/browser so handshakes complete
  4. Log the original exception inside wrap_ssl call site to identify the root cause (current code swallows it)

Example fix

# before
try:
    sock._sock = g.gae_proxy.proxy_handler.wrap_ssl(sock._sock, host, port, client_address)
except Exception as e:
    raise SslWrapFail()

# after (preserve cause for debugging)
try:
    sock._sock = g.gae_proxy.proxy_handler.wrap_ssl(sock._sock, host, port, client_address)
except Exception as e:
    xlog.warn('wrap_ssl %s fail:%r', host, e)
    raise SslWrapFail()
Defensive patterns

Strategy: retry

Validate before calling

import os
ca_ok = os.path.isfile(ca_cert_path) and os.path.isfile(ca_key_path)

Try / catch

for attempt in range(2):
    try:
        do_gae(...); break
    except SslWrapFail:
        regenerate_ca() if attempt == 0 else try_next_strategy(sock, host, port)

Prevention

When it happens

Trigger: TLS-routed GAE request where wrap_ssl throws — typical causes: CA cert/key files not generated yet, openssl errors generating per-host certificates, or client aborting the handshake.

Common situations: First run before the CA has been generated, deleted/corrupted certificate store, permission problems writing generated certs, client does not trust the CA and aborts.

Related errors


AI-assisted analysis of XX-net/XX-Net@cfa5bc17b6 (2026-08-27). Data as JSON: /api/errors/d7b1250191e20b78. Report an issue: GitHub.