Skip to content

borg2 transfer --from-borg1 fails with multiple errors with very old repos #9208

@PhrozenByte

Description

@PhrozenByte

/kind bug

When running borg2 transfer --from-borg1 with an ancient (some archives were created with Borg 1.0, maybe even Borg 0.x, but I'm not entirely sure) and "beaten" (stored on two HDDs that failed in the past, check --repair had to add all-zero replacement chunks), unencrypted/unauthenticated Borg repo (last used with Borg 1.4.3; I did run check and upgrade beforehand), the transfer fails with three different errors. Each section below describes a different issue.

After fixing all issues the transfer succeeds. borg2 check shows multiple errors though. Besides the expected inconsistencies, some expected ones are gone and some warnings don't indicate an actually all-zero replacement chunk. See the last section below for details.

I'm running Arch Linux in an unprivileged Podman container, Borg 1.4.3 installed from package sources, and Borg 2.0.0b20.dev203+ga38d87b21.d20251203 installed from Git sources.

Output of borg --version, borg2 --version, and borg info (click to expand)
(borg_venv) [root@bad113811dd4 /]# borg --version
borg 1.4.3
(borg_venv) [root@bad113811dd4 /]# borg2 --version
borg2 2.0.0b20.dev203+ga38d87b21.d20251203
(borg_venv) [root@bad113811dd4 /]# borg info -v --show-rc --progress /borg1_repo/
Warning: Attempting to access a previously unknown unencrypted repository!
Do you want to continue? [yN] y
Synchronizing chunks cache...                                                                                           
Archives: 136, w/ cached Idx: 0, w/ outdated Idx: 0, w/o cached Idx: 136.
…
Done.                                                                                                                   
Repository ID: be7bca11684be79c384cd4d08f5f344670864921b8f590c107f6016552ea37c9                                         
Location: /borg1_repo
Encrypted: No
Cache: /root/.cache/borg/be7bca11684be79c384cd4d08f5f344670864921b8f590c107f6016552ea37c9
Security dir: /root/.config/borg/security/be7bca11684be79c384cd4d08f5f344670864921b8f590c107f6016552ea37c9
------------------------------------------------------------------------------
                       Original size      Compressed size    Deduplicated size
All archives:               36.62 TB             31.75 TB            685.83 GB                                          

                       Unique chunks         Total chunks
Chunk index:                 3635180            149794103
terminating with success status, rc 0
(borg_venv) [root@bad113811dd4 /]# borg2 transfer … (see below)
(borg_venv) [root@bad113811dd4 /]# borg2 check … (see below)
(borg_venv) [root@bad113811dd4 /]# borg2 --repo=/borg2_repo/ repo-info -v --show-rc --progress
Repository ID: 1db630ef5052025edf39b2fb4ddca028bf314404d0bd2d088f520d18be90bdf5
Location: /borg2_repo
Repository version: 3
Encrypted: No
Security directory: /root/.local/share/borg/security/1db630ef5052025edf39b2fb4ddca028bf314404d0bd2d088f520d18be90bdf5
Cache: /root/.cache/borg/1db630ef5052025edf39b2fb4ddca028bf314404d0bd2d088f520d18be90bdf5

Saving cache config

terminating with success status, rc 0


AttributeError: attribute comment not found

Running borg2 --repo=/borg2_repo/ transfer --other-repo=/borg1_repo/ --from-borg1 immediately fails with the following error:

AttributeError: attribute comment not found

Offending code:

comment=archive_item.comment, # not always present?

This error occurs right away with the first archive created with Borg 1.0 (maybe even Borg 0.x) on 2016-12-31, which didn't have support for --comment yet. Looks like Thomas already had some doubts a year back in 6ce5f2f, so I'm happy to confirm these doubts today 😄

Related: #8491 fixed by #8492

Replacing the offending code with the following fixes the error (maybe None instead of ""?):

comment=archive_item.get("comment", ""),
Full command line output (click to expand)
(borg_venv) [root@039a52d2b3dd /]# borg2 --repo=/borg2_repo/ transfer -v --show-rc --progress --other-repo=/borg1_repo/ --from-borg1
Saving cache config

Local Exception

Error:

AttributeError: attribute comment not found

If reporting bugs, please include the following:

Traceback (most recent call last):
  File "/borg_repo/src/borg/archiver/__init__.py", line 651, in main
    exit_code = archiver.run(args)
  File "/borg_repo/src/borg/archiver/__init__.py", line 545, in run
    rc = func(args)
  File "/borg_repo/src/borg/archiver/_common.py", line 213, in wrapper
    return method(self, args, **kwargs)
  File "/borg_repo/src/borg/archiver/_common.py", line 143, in wrapper
    return method(self, args, repository=repository, cache=cache_, **kwargs)
  File "/borg_repo/src/borg/archiver/transfer_cmd.py", line 137, in do_transfer
    archive_infos = other_manifest.archives.list_considering(args)
  File "/borg_repo/src/borg/manifest.py", line 413, in list_considering
    return self.list(
           ~~~~~~~~~^
        sort_by=args.sort_by.split(","),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<7 lines>...
        deleted=getattr(args, "deleted", False),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/borg_repo/src/borg/manifest.py", line 388, in list
    archive_infos = self._matching_info_tuples(match, match_end, deleted=deleted)
  File "/borg_repo/src/borg/manifest.py", line 176, in _matching_info_tuples
    archive_infos = list(self._info_tuples(deleted=deleted))
  File "/borg_repo/src/borg/manifest.py", line 165, in _info_tuples
    for info in self._infos(deleted=deleted):
                ~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/borg_repo/src/borg/manifest.py", line 162, in _infos
    yield self._get_archive_meta(id)
          ~~~~~~~~~~~~~~~~~~~~~~^^^^
  File "/borg_repo/src/borg/manifest.py", line 154, in _get_archive_meta
    comment=archive_item.comment,  # not always present?
            ^^^^^^^^^^^^^^^^^^^^
  File "src/borg/item.pyx", line 221, in borg.item.PropDictProperty.__get__
AttributeError: attribute comment not found

Platform: Linux 039a52d2b3dd 6.17.9-arch1-1 #1 SMP PREEMPT_DYNAMIC Mon, 24 Nov 2025 15:21:09 +0000 x86_64
Linux: Unknown Linux  
Borg: 2.0.0b20.dev203+ga38d87b21  Python: CPython 3.13.7 msgpack: 1.1.2 fuse: None [pyfuse3,llfuse]
PID: 786  CWD: /
sys.argv: ['/borg_venv/bin/borg2', '--repo=/borg2_repo/', 'transfer', '-v', '--show-rc', '--progress', '--other-repo=/borg1_repo/', '--from-borg1']
SSH_ORIGINAL_COMMAND: None


terminating with error status, rc 2

UnboundLocalError: cannot access local variable 'chunk_entry' where it is not associated with a value

Running borg2 --repo=/borg2_repo/ transfer --other-repo=/borg1_repo/ --from-borg1 fails with the following error after fixing the issue above:

UnboundLocalError: cannot access local variable 'chunk_entry' where it is not associated with a value

Offending code:

cache.repository.async_response(wait=False)
chunks.append(chunk_entry)

This error occurs as soon as Borg attempts to transfer an all-zero replacement chunk. Following the comment in lines 75-77 I assume that lines 107+108 are supposed to run for the else case only, so it's likely just a simple indentation error (but I'm not entirely sure, I don't know Borg's code base well enough).

Indenting both lines one step further fixes the issue.

Full command line output (click to expand)
(borg_venv) [root@039a52d2b3dd /]# borg2 --repo=/borg2_repo/ transfer -v --show-rc --progress --other-repo=/borg1_repo/ --from-borg1
Dell-Vostro-2016-12-31T12:02:02 2016-12-31T11:02:03.396484+00:00 003625ed17185896fdffab6b0b4c743a6b21873899c12d1ce915181493d1148e: copying archive to destination repo...
Saving chunks cache 58415 N home/daniel/.local/share/tracker/data/tracker-store.journal.2.gz                                                                                                               
Saving cache config

Local Exception

Error:

UnboundLocalError: cannot access local variable 'chunk_entry' where it is not associated with a value

If reporting bugs, please include the following:

Traceback (most recent call last):
  File "/borg_repo/src/borg/archiver/__init__.py", line 651, in main
    exit_code = archiver.run(args)
  File "/borg_repo/src/borg/archiver/__init__.py", line 545, in run
    rc = func(args)
  File "/borg_repo/src/borg/archiver/_common.py", line 213, in wrapper
    return method(self, args, **kwargs)
  File "/borg_repo/src/borg/archiver/_common.py", line 143, in wrapper
    return method(self, args, repository=repository, cache=cache_, **kwargs)
  File "/borg_repo/src/borg/archiver/transfer_cmd.py", line 222, in do_transfer
    chunks, transfer, present = transfer_chunks(
                                ~~~~~~~~~~~~~~~^
        upgrader,
        ^^^^^^^^^
    ...<7 lines>...
        args.chunker_params,
        ^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/borg_repo/src/borg/archiver/transfer_cmd.py", line 108, in transfer_chunks
    chunks.append(chunk_entry)
                  ^^^^^^^^^^^
UnboundLocalError: cannot access local variable 'chunk_entry' where it is not associated with a value

Platform: Linux 039a52d2b3dd 6.17.9-arch1-1 #1 SMP PREEMPT_DYNAMIC Mon, 24 Nov 2025 15:21:09 +0000 x86_64
Linux: Unknown Linux  
Borg: 2.0.0b20.dev203+ga38d87b21.d20251203  Python: CPython 3.13.7 msgpack: 1.1.2 fuse: None [pyfuse3,llfuse]
PID: 1152  CWD: /
sys.argv: ['/borg_venv/bin/borg2', '--repo=/borg2_repo/', 'transfer', '-v', '--show-rc', '--progress', '--other-repo=/borg1_repo/', '--from-borg1']
SSH_ORIGINAL_COMMAND: None


terminating with error status, rc 2

AssertionError: info is None, not of type <class 'list'>

Running borg2 --repo=/borg2_repo/ transfer --other-repo=/borg1_repo/ --from-borg1 fails with the following error after fixing both issues above:

AssertionError: info is None, not of type <class 'list'>

Offending code:

assert isinstance(info, self.info_type), f"info is {info!r}, not of type {self.info_type}"

Called by:

self.hlm.remember(id=hlid, info=item.get("chunks"))

Absolutely no idea what this issue is about and what causes it. The transfer fails pretty late in the transfer for an archive created with Borg 1.4 (likely Borg 1.4.2) on 2025-11-16. Due to the other errors I resumed the transfer (i.e., I didn't start with a clean borg2 repo).

I was able to circumvent the error by replacing the calling code by the following, but this likely is just a workaround and doesn't actually fix the underlying issue:

self.hlm.remember(id=hlid, info=item.get("chunks", [])) 
Full command line output (click to expand)
(borg_venv) [root@bad113811dd4 /]# borg2 --repo=/borg2_repo/ transfer -v --show-rc --progress --other-repo=/borg1_repo/ --from-borg1
Dell-Vostro-2016-12-31T12:02:02 2016-12-31T11:02:03.396484+00:00: archive is already present in destination repo, skipping.
…
7fe919ca58b429e3c78fb466b5d5ff3447cb6bc30f52b24f4020eb9eca03e021: copying archive to destination repo...
Tuxedo-InfinityBook-14-2025-09-28T14:22:48 2025-09-28T12:22:49.527522+00:00
7fe919ca58b429e3c78fb466b5d5ff3447cb6bc30f52b24f4020eb9eca03e021: finished. transfer_size: 15.74 GB present_size: 306.10 GB                                                                           
Tuxedo-InfinityBook-14-2025-09-30T09:04:58 2025-09-30T07:04:59.320317+00:00
…
53f59dcc117c10fa6fb6f4db25cca0a471c5451a908957a8a7a17b5c0076e5a5: copying archive to destination repo...
Saving chunks cache U 978831 N srv/http/.local/share/containers/storage/overlay/3a242a69d6d2e1e9eba6b028cfbfecae083215a4fe0034ffdf9244094b51a1ee/diff1/sbin/zcip                                                                                                                  
Saving cache config

Local Exception

Error:

AssertionError: info is None, not of type <class 'list'>

If reporting bugs, please include the following:

Traceback (most recent call last):
  File "/borg_repo/src/borg/archiver/__init__.py", line 651, in main
    exit_code = archiver.run(args)
  File "/borg_repo/src/borg/archiver/__init__.py", line 545, in run
    rc = func(args)
  File "/borg_repo/src/borg/archiver/_common.py", line 213, in wrapper
    return method(self, args, **kwargs)
  File "/borg_repo/src/borg/archiver/_common.py", line 143, in wrapper
    return method(self, args, repository=repository, cache=cache_, **kwargs)
  File "/borg_repo/src/borg/archiver/transfer_cmd.py", line 239, in do_transfer
    item = upgrader.upgrade_item(item=item)
  File "/borg_repo/src/borg/upgrade.py", line 85, in upgrade_item
    self.hlm.remember(id=hlid, info=item.get("chunks"))
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/borg_repo/src/borg/helpers/fs.py", line 384, in remember
    assert isinstance(info, self.info_type), f"info is {info!r}, not of type {self.info_type}"
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
AssertionError: info is None, not of type <class 'list'>

Platform: Linux bad113811dd4 6.17.9-arch1-1 #1 SMP PREEMPT_DYNAMIC Mon, 24 Nov 2025 15:21:09 +0000 x86_64
Linux: Unknown Linux  
Borg: 2.0.0b20.dev203+ga38d87b21.d20251203  Python: CPython 3.13.7 msgpack: 1.1.2 fuse: None [pyfuse3,llfuse]
PID: 773  CWD: /
sys.argv: ['/borg_venv/bin/borg2', '--repo=/borg2_repo/', 'transfer', '-v', '--show-rc', '--progress', '--other-repo=/borg1_repo/', '--from-borg1']
SSH_ORIGINAL_COMMAND: None


terminating with error status, rc 2

Unexpected inconsistencies found by borg2 check

Running borg2 --repo=/borg2_repo/ check after borg2 transfer (after fixing all issues above) causes check to report a lot of inconsistencies. This is expected for all-zero replacement chunks, but a few things are weird:

  • Some expected inconsistencies are gone. For example, borg check (Borg 1.4) reports a few missing chunks for the 2016-12-31 archive also mentioned earlier (it actually caused the second error above), but borg2 check reports no inconsistencies for the same archive. This is true for multiple archives actually, but not all. Even though I don't know the exact Borg versions used to create what archive (related: it might be a good idea to add this info to the archive metadata), I assume (!) that the affected archives were created with Borg 1.0 or Borg 0.x, whereas all other archives were created with Borg 1.1 or later. Anyway, either Borg 1.4 is at fault and fails to repair a chunk that Borg 2 could repair while transferring the archive, or Borg 2 isn't reporting an inconsistent chunk. Any ideas?

  • Some inconsistencies are reported in chunks with a size of >0 bytes. For all-zero replacement chunks I'd expect size inconsistency detected: size ???, chunks size 0 warnings only, but there are others as well. However, if comparing the list of affected files per archive, both lists are identical (besides the mentioned archives above). Is this expected (like "all-zero" doesn't really mean "all-zero")?

    Tuxedo-InfinityBook-14-2019-12-31T12:36:48: home/daniel/some/path: size inconsistency detected: size 1829, chunks size 0
    Tuxedo-InfinityBook-14-2020-12-30T15:47:15: var/lib/snapd/snaps/phpstorm_193.snap: size inconsistency detected: size 429719552, chunks size 426630659
    
Full command line output (click to expand)
(borg_venv) [root@bad113811dd4 /]# borg2 --repo=/borg2_repo/ check -v --show-rc --progress
Starting full repository check
Starting from beginning.
Checkpointing at key data/1093d94dda17041328255467f200df24aa5998600b2c4e4f9571114fe1129edb.
…
Checkpointing at key data/f7c0aaa93ad6cb912a714ab636f2166aa7aab6148c044e2471cb1b30ffd6615c.
Finished repository check.
Checked 3658563 repository objects, 0 errors.
Finished full repository check, no problems found.
Starting archive consistency check...
Checking archives 0.0%
Analyzing archive Dell-Vostro-2016-12-31T12:02:02 2016-12-31 11:02:03.396484+00:00 48decb3131eaecf375d2267de209f0e06d259025864e481495c5c645ae8343e9 (1/137)
…
Analyzing archive Tuxedo-InfinityBook-14-2019-12-31T12:36:48 2019-12-31 11:36:53.695344+00:00 fa7d5ded7eaba59fee5bca362b3fbd5850e49e9e1231a8ea3f125d65ec3bb3d8 (4/137)
Tuxedo-InfinityBook-14-2019-12-31T12:36:48: home/daniel/some/path: size inconsistency detected: size 1829, chunks size 0
…
Checking archives 2.9%
Analyzing archive Tuxedo-InfinityBook-14-2020-12-30T15:47:15 2020-12-30 14:47:21.902702+00:00 081ee458d4439cea699517af0c6058f8c39220f386879df1ead10bced817bbea (5/137)
Tuxedo-InfinityBook-14-2020-12-30T15:47:15: var/lib/snapd/snaps/phpstorm_193.snap: size inconsistency detected: size 429719552, chunks size 426630659
…
Checking archives 99.3%
Analyzing archive Tuxedo-InfinityBook-14-2025-12-03T12:01:26 2025-12-03 11:01:27.681778+00:00 5a44bae062ad6b55d13202f307c317c74592940218d3aec815bcca61499e148c (137/137)

Archive consistency check complete, no problems found.
terminating with success status, rc 0

Metadata

Metadata

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions