#951696 requests: incompatibility between requests == 2.22.0-2

Package:
requests
Source:
requests
Submitter:
abeelen
Date:
2026-06-30 15:53:02 UTC
Severity:
important
Tags:
#951696#5
Date:
2020-02-20 09:22:54 UTC
From:
To:
Dear Maintainer,

When run with python3-urllib3=1.25-8-1, certbot fails to run with a traceback :

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/requests/models.py", line 379, in prepare_url
    scheme, auth, host, port, path, query, fragment = parse_url(url)
  File "/usr/lib/python3/dist-packages/urllib3/util/url.py", line 392, in parse_url
    return six.raise_from(LocationParseError(source_url), None)
  File "<string>", line 3, in raise_from
urllib3.exceptions.LocationParseError: Failed to parse: https://acme-v02.api.letsencrypt.org/directory

downgrading to python3-urllib3=1.24.1-1 solve this issue.

#951696#10
Date:
2020-02-21 04:29:44 UTC
From:
To:
Hello Alexandre,

Can you please tell me exactly what command you're running when
certbot gives you that stacktrace?  Can you also let me know what
version of python3-requests you have? That looks like a
requests/urllib3 incompatibility, but I can't reproduce it by hand or
inside certbot.

Sincerely,

#951696#15
Date:
2020-02-21 09:10:09 UTC
From:
To:
Hi,

I was simply trying to renew my certificate with

certbot renew

Also try to obtain new certificate after ditching /etc/letsencrypt to
make sure it was not a configuration problem, with the same outcome

it works with :

python3-requests                       2.22.0-2
python3-urllib3                        1.24.1-1

it fails with :

python3-requests                       2.22.0-2
python3-urllib3                        1.25.8-1

a.

#951696#20
Date:
2020-03-27 15:43:36 UTC
From:
To:
reassign 951696 requests
retitle 951696 requests: incompatibility between requests == 2.22.0-2
and urllib3 == 1.25.8-1
tag 951696 +unreproducible
affects 951696 certbot python3-urllib3
thanks

I've looked over this several times over the last few months, and I
can't reproduce the problem on any of my test systems.  However,
looking at the code, if this bug exists, it's definitely between
requests and urllib3, not in certbot itself.

Sending it over to the requests folks, in the hopes that they've seen
this somewhere else and can reproduce it.

Sincerely,

On Fri, Feb 21, 2020 at 4:10 AM Alexandre Beelen <alexandre.beelen@gmail.com> wrote:

#951696#35
Date:
2020-03-28 00:51:19 UTC
From:
To:
Hello Harlan,
thanks for forwarding this!
I would exclude requests involvement for now, it seems more on urllib3 side,
but let's see (anyway no need to move this now, since I maintain also urllib3).
I strictly follow upstream for compatibility versions, so I'm more
inclined to ithink to an urllib3 bug.

I looked at the differences of urllib3.util.url.parse_url in 1.25.8-1 and
1.24.1-1: upstream moved to a more "ask forgiveness" approach, and we can see
a try/except block from line 360 to line 391.
The except is:

    except (ValueError, AttributeError):
        return six.raise_from(LocationParseError(source_url), None)

So although Python 3 can chain exceptions since None is passed to
six.raise_from, every exceptions of kind ValueError or AttributeError are
masked as the LocationParseError we see in the traceback that Alexandre posted.
This can hide a possible root cause and I would look at this first.

@Alexandre since it seems tricky to reproduce, meanwhile I setup a test
environment, please can you try to unmask the exception above?
You need only to edit the lines above (lines 391 and 392 of
/usr/lib/python3/dist-packages/urllib3/util/url.py) into:

    except (ValueError, AttributeError) as exp:
        return six.raise_from(LocationParseError(source_url), exp)

This way you should get also the traceback of another exception that is
eventually raised.
Or you can just rethrow `exp`: choose the way you prefer.

From the exception we get now it's not possible to understand what is
happening. The source_url mentioned in the first report is parsed fine in my
system with urllib3 1.25.8-1:

❯ python3 -c "from urllib3.util.url import parse_url; print(repr(parse_url('https://acme-v02.api.letsencrypt.org/directory')))"
Url(scheme='https', auth=None, host='acme-v02.api.letsencrypt.org', port=None, path='/directory', query=None, fragment=None)

So maybe there is something hidden somewhere.

Regards,

#951696#40
Date:
2026-06-30 15:44:19 UTC
From:
To:
Let's close this report as no new insights did come up and the reported
version now six years old!

Regards
Carsten