treeverse / treeverse/dvc

dvc list: fails with ssh when using dulwich >= 1.2.8

Open
#11,065 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
15.9k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Description

Bug Report

Description

When running the command
poetry run dvc list ssh://some-repo data/some-dataset -R -v
dvc gets stuck at cloning the repository.

When running
GIT_SSH_COMMAND="ssh -o BatchMode=yes -o StrictHostKeyChecking=yes" poetry run dvc list ssh://some-repo data/some-dataset -R -v
we get the following error:

2026-07-10 10:52:20,059 DEBUG: v3.67.1 (pip), CPython 3.12.12 on Linux-4.18.0-553.22.1.el8_10.x86_64-x86_64-with-glibc2.28
2026-07-10 10:52:20,059 DEBUG: command: /some_path/.venv/bin/dvc list ssh://some-repo some-dataset -R -v
2026-07-10 10:52:20,281 DEBUG: Creating external repo ssh://some-repo@None
2026-07-10 10:52:20,281 DEBUG: erepo: git clone 'ssh://some-repo' to a temporary dir
2026-07-10 10:52:20,837 ERROR: failed to list 'ssh://some-repo' - SCM error: Failed to clone repo 'ssh://some-repo' to '/tmp/tmp2g0qc5madvc-clone': The remote server unexpectedly closed the connection.
Traceback (most recent call last):
  File "/some_path/.venv/lib/python3.12/site-packages/scmrepo/git/backend/dulwich/__init__.py", line 261, in clone
    repo = clone_from()
           ^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dulwich/porcelain/__init__.py", line 1593, in clone
    repo = client.clone(
           ^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dulwich/client.py", line 1528, in clone
    result = self.fetch(
             ^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dulwich/client.py", line 1671, in fetch
    result = self.fetch_pack(
             ^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dulwich/client.py", line 2217, in fetch_pack
    server_protocol_version = negotiate_protocol_version(proto)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dulwich/client.py", line 412, in negotiate_protocol_version
    pkt = proto.read_pkt_line()
          ^^^^^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dulwich/protocol.py", line 493, in read_pkt_line
    raise HangupException
dulwich.errors.HangupException: The remote server unexpectedly closed the connection.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/some_path/.venv/lib/python3.12/site-packages/dvc/scm.py", line 153, in clone
    git = Git.clone(url, to_path, progress=pbar.update_git, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/scmrepo/git/__init__.py", line 156, in clone
    backend.clone(url, to_path, bare=bare, mirror=mirror, **kwargs)
  File "/some_path/.venv/lib/python3.12/site-packages/scmrepo/git/backend/dulwich/__init__.py", line 269, in clone
    raise CloneError(url, os.fsdecode(to_path)) from exc
scmrepo.exceptions.CloneError: Failed to clone repo 'ssh://some-repo' to '/tmp/tmp2g0qc5madvc-clone'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/some_path/.venv/lib/python3.12/site-packages/dvc/commands/ls/__init__.py", line 177, in run
    return self._show_list()
           ^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dvc/commands/ls/__init__.py", line 148, in _show_list
    entries = Repo.ls(
              ^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dvc/repo/ls.py", line 81, in ls
    with _open_repo(url, rev, config, remote, remote_config) as repo:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dvc/repo/ls.py", line 24, in _open_repo
    return Repo.open(
           ^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dvc/repo/__init__.py", line 306, in open
    return open_repo(url, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dvc/repo/open_repo.py", line 60, in open_repo
    return _external_repo(url, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ldap/u237427/.pyenv/versions/3.12.12/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dvc/repo/open_repo.py", line 23, in _external_repo
    path = _cached_clone(url, rev)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dvc/repo/open_repo.py", line 140, in _cached_clone
    clone_path, shallow = _clone_default_branch(url, rev)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/funcy/decorators.py", line 47, in wrapper
    return deco(call, *dargs, **dkwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/funcy/flow.py", line 246, in wrap_with
    return call()
           ^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/funcy/decorators.py", line 68, in __call__
    return self._func(*self._args, **self._kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dvc/repo/open_repo.py", line 204, in _clone_default_branch
    git = clone(url, clone_path)
          ^^^^^^^^^^^^^^^^^^^^^^
  File "/some_path/.venv/lib/python3.12/site-packages/dvc/scm.py", line 158, in clone
    raise CloneError("SCM error") from exc
dvc.scm.CloneError: SCM error

2026-07-10 10:52:20,857 DEBUG: Analytics is enabled.
2026-07-10 10:52:20,904 DEBUG: Trying to spawn ['daemon', 'analytics', '/tmp/tmpp4p7z2pb', '-v']
2026-07-10 10:52:20,911 DEBUG: Spawned ['daemon', 'analytics', '/tmp/tmpp4p7z2pb', '-v'] with pid 3373789

When downgrading dulwich to a version below 1.2.8, it works

Reproduce
  1. create the following pyproject repo:
#----------------- pyproject.toml--------------------------------:
[tool.poetry]
name = "dummy-project"
version = "0.0.0" # Version is ignored and set jenkins. Use pipeline to increase.
description = ""

[tool.poetry.dependencies]
python = "~3.13"

[tool.poetry.group.dvc]
optional = true

[tool.poetry.group.dvc.dependencies]
dvc = { extras = ["azure"], version = "3.67.1" }

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

  1. Run poetry lock
  2. Run poetry install --with dvc --no-root
  3. Run poetry run dvc list ssh://git@some-repo data/some-dataset -R -v
    and GIT_SSH_COMMAND="ssh" poetry run dvc list ssh://git@some-repo data/some-dataset -R -v
Expected

I expect there to be no error showing with the second command and with the first command it should not stay stuck at cloning

Environment information

Output of dvc doctor:

$ dvc doctor

DVC version: 3.67.1 (pip)
-------------------------
Platform: Python 3.13.3 on Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.35
Subprojects:
        dvc_data = 3.18.3
        dvc_objects = 5.2.0
        dvc_render = 1.0.2
        dvc_task = 0.40.2
        scmrepo = 3.6.2
Supports:
        azure (adlfs = 2026.5.0, knack = 0.14.0, azure-identity = 1.25.3),
        http (aiohttp = 3.14.1, aiohttp-retry = 2.9.1),
        https (aiohttp = 3.14.1, aiohttp-retry = 2.9.1)
Config:
        Global: /home/u237427/.config/dvc
        System: /etc/xdg/dvc

Additional Information (if any):

This commit here could be a possible issue: https://github.com/jelmer/dulwich/pull/2254

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with dvc list against an SSH repository using dulwich 1.2.8 or newer, then trace the clone path through dvc/repo/open_repo.py and dvc/scm.py into scmrepo's dulwich backend. Compare the behavior with an older dulwich version and the referenced dulwich pull request. Done means SSH cloning no longer hangs or raises the reported error, with a regression test covering the command.

Written by the indexing model from the issue text.

Assessment

Tech stack
git, python
Domain
backend, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.