-
-
Notifications
You must be signed in to change notification settings - Fork 804
Description
/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:
Line 154 in a38d87b
| 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 😄
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:
borg/src/borg/archiver/transfer_cmd.py
Lines 107 to 108 in a38d87b
| 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:
Line 384 in a38d87b
| assert isinstance(info, self.info_type), f"info is {info!r}, not of type {self.info_type}" |
Called by:
Line 85 in a38d87b
| 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), butborg2 checkreports 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 0warnings 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