{"record":{"id":"7c8b76bf5bbb9fa8","repo":"arduino/Arduino","slug":"sslerror-e-7c8b76","errorCode":null,"errorMessage":"SSLError(e)","messagePattern":"SSLError\\(e\\)","errorType":"exception","errorClass":"SSLError","httpStatus":null,"severity":"error","filePath":"arduino-core/src/processing/app/i18n/python/requests/packages/urllib3/util.py","lineNumber":324,"sourceCode":"    def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,\n                        ca_certs=None, server_hostname=None,\n                        ssl_version=None):\n        \"\"\"\n        All arguments except `server_hostname` have the same meaning as for\n        :func:`ssl.wrap_socket`\n\n        :param server_hostname:\n            Hostname of the expected certificate\n        \"\"\"\n        context = SSLContext(ssl_version)\n        context.verify_mode = cert_reqs\n        if ca_certs:\n            try:\n                context.load_verify_locations(ca_certs)\n            # Py32 raises IOError\n            # Py33 raises FileNotFoundError\n            except Exception as e:  # Reraise as SSLError\n                raise SSLError(e)\n        if certfile:\n            # FIXME: This block needs a test.\n            context.load_cert_chain(certfile, keyfile)\n        if HAS_SNI:  # Platform-specific: OpenSSL with enabled SNI\n            return context.wrap_socket(sock, server_hostname=server_hostname)\n        return context.wrap_socket(sock)\n\nelse:  # Python 3.1 and earlier\n    def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None,\n                        ca_certs=None, server_hostname=None,\n                        ssl_version=None):\n        return wrap_socket(sock, keyfile=keyfile, certfile=certfile,\n                           ca_certs=ca_certs, cert_reqs=cert_reqs,\n                           ssl_version=ssl_version)\n","sourceCodeStart":306,"sourceCodeEnd":339,"githubUrl":"https://github.com/arduino/Arduino/blob/a0df6e0e83b652c72bc78b0a1376c54d6ebc3bee/arduino-core/src/processing/app/i18n/python/requests/packages/urllib3/util.py#L306-L339","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Use certifi's bundle: requests.get(url, verify=certifi.where()) or verify=True with a correctly set CA path.","Fix the env vars REQUESTS_CA_BUNDLE / SSL_CERT_FILE / CURL_CA_BUNDLE if they point to nonexistent files.","If the bundle is malformed, regenerate or re-export it (full chain PEM, correct line endings)."],"exampleFix":"// before\nrequests.get(url, verify='/etc/ssl/old-ca-bundle.crt')  # SSLError: file missing\n// after\nimport certifi\nrequests.get(url, verify=certifi.where())","handlingStrategy":"validation","validationCode":"import os\ncab = os.environ.get('REQUESTS_CA_BUNDLE') or ca_certs\nif cab:\n    assert os.path.isfile(cab), 'CA bundle not found: %s' % cab\n    with open(cab, 'rb') as f:\n        data = f.read()\n    assert b'BEGIN CERTIFICATE' in data, 'CA bundle has no PEM certificates: %s' % cab","typeGuard":null,"tryCatchPattern":"from requests.exceptions import SSLError\ntry:\n    resp = requests.get(url, verify=ca_bundle)\nexcept SSLError as e:\n    if 'No such file' in str(e) or 'permission' in str(e).lower():\n        resp = requests.get(url, verify=certifi.where())\n    else:\n        raise","preventionTips":["Always source CA bundles from certifi.where() rather than hard-coded paths.","Audit REQUESTS_CA_BUNDLE / SSL_CERT_FILE / CURL_CA_BUNDLE in Docker images and CI.","Validate bundle contents (PEM format, readable) at application startup.","Re-check bundle paths after OS/base-image upgrades."],"tags":["ssl","ca-bundle","certificate","network","file-not-found"],"backgroundTag":"file-not-found","analyzedSha":"a0df6e0e83b652c72bc78b0a1376c54d6ebc3bee","analyzedAt":"2026-09-06T10:13:38.901Z","contentChangedAt":"2026-09-06T10:13:38.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}