arduino/Arduino · error · SSLError

SSLError(e)

Error message

SSLError(e)

What it means

ssl_wrap_socket wraps low-level SSL setup failures (here, loading the CA bundle via context.load_verify_locations) into an SSLError. When the ca_certs file path cannot be read or is not a valid PEM/DER certificate bundle, the original exception is re-raised as SSLError(e).

Source

Thrown at arduino-core/src/processing/app/i18n/python/requests/packages/urllib3/util.py:324

    def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
                        ca_certs=None, server_hostname=None,
                        ssl_version=None):
        """
        All arguments except `server_hostname` have the same meaning as for
        :func:`ssl.wrap_socket`

        :param server_hostname:
            Hostname of the expected certificate
        """
        context = SSLContext(ssl_version)
        context.verify_mode = cert_reqs
        if ca_certs:
            try:
                context.load_verify_locations(ca_certs)
            # Py32 raises IOError
            # Py33 raises FileNotFoundError
            except Exception as e:  # Reraise as SSLError
                raise SSLError(e)
        if certfile:
            # FIXME: This block needs a test.
            context.load_cert_chain(certfile, keyfile)
        if HAS_SNI:  # Platform-specific: OpenSSL with enabled SNI
            return context.wrap_socket(sock, server_hostname=server_hostname)
        return context.wrap_socket(sock)

else:  # Python 3.1 and earlier
    def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,
                        ca_certs=None, server_hostname=None,
                        ssl_version=None):
        return wrap_socket(sock, keyfile=keyfile, certfile=certfile,
                           ca_certs=ca_certs, cert_reqs=cert_reqs,
                           ssl_version=ssl_version)

View on GitHub (pinned to a0df6e0e83)

Solutions

  1. Verify the CA bundle path exists and is readable: `ls -l $(python -c 'import certifi; print(certifi.where())')` and fix the verify/ca_certs value.
  2. Use certifi's bundle: requests.get(url, verify=certifi.where()) or verify=True with a correctly set CA path.
  3. Fix the env vars REQUESTS_CA_BUNDLE / SSL_CERT_FILE / CURL_CA_BUNDLE if they point to nonexistent files.
  4. If the bundle is malformed, regenerate or re-export it (full chain PEM, correct line endings).

Example fix

// before
requests.get(url, verify='/etc/ssl/old-ca-bundle.crt')  # SSLError: file missing
// after
import certifi
requests.get(url, verify=certifi.where())
Defensive patterns

Strategy: validation

Validate before calling

import os
cab = os.environ.get('REQUESTS_CA_BUNDLE') or ca_certs
if cab:
    assert os.path.isfile(cab), 'CA bundle not found: %s' % cab
    with open(cab, 'rb') as f:
        data = f.read()
    assert b'BEGIN CERTIFICATE' in data, 'CA bundle has no PEM certificates: %s' % cab

Try / catch

from requests.exceptions import SSLError
try:
    resp = requests.get(url, verify=ca_bundle)
except SSLError as e:
    if 'No such file' in str(e) or 'permission' in str(e).lower():
        resp = requests.get(url, verify=certifi.where())
    else:
        raise

Prevention

When it happens

Trigger: Passing verify='/path/to/ca-bundle.crt' (requests) or ca_certs=... (urllib3) where the file does not exist, has wrong permissions, is empty, or contains malformed certificates; Py32 raises IOError / Py33 FileNotFoundError, both caught and re-raised as SSLError.

Common situations: REQUESTS_CA_BUNDLE or SSL_CERT_FILE env var pointing at a missing/invalid path; Docker/slim images without certifi's bundle; stale hard-coded paths after deployment; bundling an intermediate-only or corrupted PEM file.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of arduino/Arduino@a0df6e0e83 (2026-09-06). Data as JSON: /api/errors/7c8b76bf5bbb9fa8. Report an issue: GitHub.