#2056·pip-tools

Hashes are used although pip-compile was instructed to compile from scratch using --rebuild

Author: manuel-kochCreated Feb 19, 2024Updated Jul 30, 2026

Environment Versions

  1. MacOS, 14.3.1 (23D60), arm64
  2. Python version: $ python -V: Python 3.10.6
  3. pip version: $ pip --version: pip 24.0
  4. pip-tools version: $ pip-compile --version: pip-compile, version 7.4.0

Scenario

Using a private PyPi repository, the same version of a package was published multiple times using different hashes between consecutive invocations of pip-compile.

The scenario is as follows:

  • Initial version of package was published in the private PyPi repo
  • Running pip-compile --verbose --no-emit-index-url --rebuild --resolver=backtracking /Users/user/myproject/requirements.in
  • Same version of package, with different content was published in the private PyPi repo
  • Running pip-compile --verbose --no-emit-index-url --rebuild --resolver=backtracking /Users/user/myproject/requirements.in again

The second run of pip-compile complains about a possible tampered package - but I have not put any hashes in the requirements.in or the previously compiled requirements.txt.

The output of the second run of pip-compile:

python-traceback
$ pip-compile --verbose --no-emit-index-url --rebuild --resolver=backtracking /Users/user/myproject/requirements.in
Using pip-tools configuration defaults found in 'pyproject.toml'.
Using indexes:
  https://user:****@custom-pypi/simple
  Looking in indexes: https://user:****@custom-pypi/simple

                          ROUND 1                           
  Collecting more-itertools~=10.2 (from -r /Users/user/myproject/requirements.in (line 2))
    Using cached https://custom-pypi/packages/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl (57 kB)
  ....
  Collecting my-lib-package~=5.0.4rc0 (from -r /Users/user/myproject/requirements.in (line 38))
    Using cached https://custom-pypi/my-lib-package/5.0.4rc0/my_lib_package-5.0.4rc0-py3-none-any.whl (72 kB)
Traceback (most recent call last):
  File "/python3.10/bin/pip-compile", line 8, in <module>
    sys.exit(cli())
  File "/python3.10/lib/python3.10/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "/python3.10/lib/python3.10/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "/python3.10/lib/python3.10/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/python3.10/lib/python3.10/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "/python3.10/lib/python3.10/site-packages/click/decorators.py", line 33, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/python3.10/lib/python3.10/site-packages/piptools/scripts/compile.py", line 469, in cli
    results = resolver.resolve(max_rounds=max_rounds)
  File "/python3.10/lib/python3.10/site-packages/piptools/resolver.py", line 604, in resolve
    is_resolved = self._do_resolve(
  File "/python3.10/lib/python3.10/site-packages/piptools/resolver.py", line 636, in _do_resolve
    resolver.resolve(
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/resolver.py", line 95, in resolve
    result = self._result = resolver.resolve(
  File "/python3.10/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 546, in resolve
    state = resolution.resolve(requirements, max_rounds=max_rounds)
  File "/python3.10/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 397, in resolve
    self._add_to_criteria(self.state.criteria, r, parent=None)
  File "/python3.10/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 173, in _add_to_criteria
    if not criterion.candidates:
  File "/python3.10/lib/python3.10/site-packages/pip/_vendor/resolvelib/structs.py", line 156, in __bool__
    return bool(self._sequence)
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py", line 155, in __bool__
    return any(self)
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py", line 143, in <genexpr>
    return (c for c in iterator if id(c) not in self._incompatible_ids)
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py", line 47, in _iter_built
    candidate = func()
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/factory.py", line 182, in _make_candidate_from_link
    base: Optional[BaseCandidate] = self._make_base_candidate_from_link(
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/factory.py", line 228, in _make_base_candidate_from_link
    self._link_candidate_cache[link] = LinkCandidate(
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 290, in __init__
    super().__init__(
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 156, in __init__
    self.dist = self._prepare()
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 222, in _prepare
    dist = self._prepare_distribution()
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 301, in _prepare_distribution
    return preparer.prepare_linked_requirement(self._ireq, parallel_builds=True)
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/operations/prepare.py", line 525, in prepare_linked_requirement
    return self._prepare_linked_requirement(req, parallel_builds)
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/operations/prepare.py", line 596, in _prepare_linked_requirement
    local_file = unpack_url(
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/operations/prepare.py", line 168, in unpack_url
    file = get_http_url(
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/operations/prepare.py", line 111, in get_http_url
    hashes.check_against_path(from_path)
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/utils/hashes.py", line 106, in check_against_path
    return self.check_against_file(file)
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/utils/hashes.py", line 102, in check_against_file
    return self.check_against_chunks(read_chunks(file))
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/utils/hashes.py", line 91, in check_against_chunks
    self._raise(gots)
  File "/python3.10/lib/python3.10/site-packages/pip/_internal/utils/hashes.py", line 94, in _raise
    raise HashMismatch(self._allowed, gots)
pip._internal.exceptions.HashMismatch: THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
    my-lib-package~=5.0.4rc0 from https://custom-pypi/my-lib-package/5.0.4rc0/my_lib_package-5.0.4rc0-py3-none-any.whl#sha256=7f9d3fc72d7e1e1fa4aabae5327579e8291b0f103ebc57d89d7afac1c69462ff (from -r /Users/user/myproject/requirements.in (line 38)):
        Expected sha256 7f9d3fc72d7e1e1fa4aabae5327579e8291b0f103ebc57d89d7afac1c69462ff
             Got        7c5f0f5ed128d985f11a10353f0bb62a046892c292b5b7975e3bf0763ff89e0a

Where does pip-compile get the earlier hash from ? How can I configure pip-compile to really compile dependencies from scratch ? Why does --rebuild still reuse pre-existing hashes when those hashes are absent from any requirements.in or requirements.txt ?