Skip to content

documentation for requests.session.request(verify=...) duplicates requests.request() even where it is different #7399

@biredel

Description

@biredel

Docs currently state:

Either a boolean, in which case it controls whether we verify the server’s TLS certificate, or a string, in which case it must be a path to a CA bundle to use. Defaults to True.

I suggest rewording both statements, because as they stand they make figuring what went wrong with setting the correct CA bundle way harder than it should be:

  1. Passing bool not only controls whether the certificate is verified, it also resets the root store to be verified against.
  2. The default for the method does not behave like True - leaving it unspecified simply defers to the session, as it should.. session in turn may very well have verify=False.
  3. (still incomplete because of os.environ precedence, but I understand that one is currently #WONTFIX as per Session.verify=False ignored when REQUESTS_CA_BUNDLE environment variable is set #3829)

Documentation appears to state

s.verify=True s.verify="/S" s.verify=False
s.request(verify=True) True ✅ "/S" True
s.request(verify="/r") "/r" "/r" "/r"
s.request(verify=False) False False False
s.request() # i.e. s.request(verify=None) True ⚠️True ⚠️True

Actual Result

s.verify=True s.verify="/S" s.verify=False
s.request(verify=True) True ⚠️True True
s.request(verify="/r") "/r" "/r" "/r"
s.request(verify=False) False False False
s.request() # i.e. s.request(verify=None) True ✅"/S" ✅ False

Reproduction Steps

>>> import certifi,requests,ssl,os
>>> certifi.__version__
'2026.04.22'
>>> certifi.where()
'/inaccessible/path'
>>> requests.__version__
'2.33.1'
>>> session = requests.session()
>>> session.verify = ssl.get_default_verify_paths().capath
>>> os.path.isdir(session.verify)
True
>>> session.request(url="https://example.com", method="HEAD")
<Response [200]>
>>> session.request(url="https://example.com", method="HEAD", verify=True)
Traceback (most recent call last):
[..]
  File "/home/user/lib/python3.10/site-packages/requests/adapters.py", line 304, in cert_verify
    raise OSError(
OSError: Could not find a suitable TLS CA certificate bundle, invalid path: /inaccessible/path

This result means that libraries that opt to use the supposedly-default parameter value of True are doing something meaningfully different from those that use the actual-default parameter of None (typically: by not mentioning the parameter).

System Information

$ python -m requests.help
{
  "chardet": {
    "version": "4.0.0"
  },
  "charset_normalizer": {
    "version": "3.4.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "3.3"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.10.12"
  },
  "platform": {
    "release": "6.8.0-110-generic",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.33.1"
  },
  "system_ssl": {
    "version": "30000020"
  },
  "urllib3": {
    "version": "2.6.3"
  },
  "using_charset_normalizer": false,
  "using_pyopenssl": false
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    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