Request service download_chunks crashes with unhandled ChunkedEncodingError when a remote-build artifact download breaks mid-transfer, forcing a full rebuild. No retry logic exists in the code at HEAD; issue is unlabeled with no maintainer activity for ~7 months.
Suggested action: needs triage
Reason: The issue has no labels, no assignee, and zero comments from maintainers, showing no triage has occurred. It is not stale-closable because the code at HEAD still lacks retry in download_chunks (verified in craft_application/services/request.py), and the repo already has a retry utility (craft_application/util/retry.py) used for Launchpad calls that could be adapted, so the request remains actionable. Complexity is moderate because retrying a streaming download requires restarting/truncating the partial file and reworking the progress-bar loop in download_files_with_progress.
### What needs to get done
When using `remote-build` service in `rockcraft`, there are often build failures caused by network instabilities.
The network instability causes the unhandled `ChunkedEncodingError` exception inside `craft_application/services/request.py", line 71, in download_chunks`.
When the `*craft` tool is downloading the artifact from the build farm, it should be able to retry upon broken connections, such that when using `*craft` tools in CI, the occasional failures happening during the download would not lead to a full rebuild.
A log of such an error is attached below:
```
2026-01-23 17:16:25.270 Succeeded: amd64, arm64, armhf, ppc64el, riscv64, s390x
2026-01-23 17:16:25.271 Fetching build artifacts...
2026-01-23 17:16:31.933 Downloading 6 files (--->)
2026-01-23 17:17:38.222 Downloading 6 files (<---)
2026-01-23 17:17:38.228 rockcraft internal error: ChunkedEncodingError(ProtocolError('Connection broken: IncompleteRead(14610378 bytes read, 25147446 more expected)', IncompleteRead(14610378 bytes read, 25147446 more expected)))
2026-01-23 17:17:38.255 Traceback (most recent call last):
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/urllib3/response.py", line 779, in _error_catcher
2026-01-23 17:17:38.255 yield
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/urllib3/response.py", line 904, in _raw_read
2026-01-23 17:17:38.255 data = self._fp_read(amt, read1=read1) if not fp_closed else b""
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/urllib3/response.py", line 887, in _fp_read
2026-01-23 17:17:38.255 return self._fp.read(amt) if amt is not None else self._fp.read()
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/current/usr/lib/python3.12/http/client.py", line 495, in read
2026-01-23 17:17:38.255 s = self._safe_read(self.length)
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/current/usr/lib/python3.12/http/client.py", line 642, in _safe_read
2026-01-23 17:17:38.255 raise IncompleteRead(data, amt-len(data))
2026-01-23 17:17:38.255 http.client.IncompleteRead: IncompleteRead(14610378 bytes read, 25147446 more expected)
2026-01-23 17:17:38.255
2026-01-23 17:17:38.255 The above exception was the direct cause of the following exception:
2026-01-23 17:17:38.255 Traceback (most recent call last):
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/requests/models.py", line 820, in generate
2026-01-23 17:17:38.255 yield from self.raw.stream(chunk_size, decode_content=True)
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/urllib3/response.py", line 1091, in stream
2026-01-23 17:17:38.255 data = self.read(amt=amt, decode_content=decode_content)
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/urllib3/response.py", line 980, in read
2026-01-23 17:17:38.255 data = self._raw_read(amt)
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/urllib3/response.py", line 903, in _raw_read
2026-01-23 17:17:38.255 with self._error_catcher():
2026-01-23 17:17:38.255 File "/snap/rockcraft/current/usr/lib/python3.12/contextlib.py", line 158, in __exit__
2026-01-23 17:17:38.255 self.gen.throw(value)
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/urllib3/response.py", line 806, in _error_catcher
2026-01-23 17:17:38.255 raise ProtocolError(f"Connection broken: {e!r}", e) from e
2026-01-23 17:17:38.255 urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(14610378 bytes read, 25147446 more expected)', IncompleteRead(14610378 bytes read, 25147446 more expected))
2026-01-23 17:17:38.255
2026-01-23 17:17:38.255 During handling of the above exception, another exception occurred:
2026-01-23 17:17:38.255 Traceback (most recent call last):
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/craft_application/application.py", line 669, in run
2026-01-23 17:17:38.255 return_code = self._run_inner()
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/craft_application/application.py", line 646, in _run_inner
2026-01-23 17:17:38.255 return_code = dispatcher.run() or os.EX_OK
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/craft_cli/dispatcher.py", line 564, in run
2026-01-23 17:17:38.255 return self._loaded_command.run(self._parsed_command_args)
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/craft_application/commands/base.py", line 222, in run
2026-01-23 17:17:38.255 result = self._run(parsed_args, **kwargs) or result
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/craft_application/commands/remote.py", line 165, in _run
2026-01-23 17:17:38.255 returncode = self._monitor_and_complete(builds=builds)
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/craft_application/commands/remote.py", line 224, in _monitor_and_complete
2026-01-23 17:17:38.255 artifacts = builder.fetch_artifacts(pathlib.Path.cwd())
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/craft_application/services/remotebuild.py", line 207, in fetch_artifacts
2026-01-23 17:17:38.255 return self.request.download_files_with_progress(artifact_downloads).values()
2026-01-23 17:17:38.255 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/craft_application/services/request.py", line 109, in download_files_with_progress
2026-01-23 17:17:38.255 for chunk_size in dl:
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/craft_application/services/request.py", line 71, in download_chunks
2026-01-23 17:17:38.255 for chunk in download.iter_content(None):
2026-01-23 17:17:38.255 File "/snap/rockcraft/3974/lib/python3.12/site-packages/requests/models.py", line 822, in generate
2026-01-23 17:17:38.255 raise ChunkedEncodingError(e)
2026-01-23 17:17:38.255 requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(14610378 bytes read, 25147446 more expected)', IncompleteRead(14610378 bytes read, 25147446 more expected))
```
### Why it needs to get done
As `remote-build` can take a long time to be built, purging a successful build with a single failed download attempt seems very inefficient and wasteful. We should let `*craft` tools give multiple tries to improve the chances of successful builds.
Evaluation history
Date
Model
Scores
Action
Summary
qwen/qwen3.8-27b
Impact:
55
Quick Win:
30.25
Staleness:
65
Complexity:
45
Confidence:
80
Support Request:
10
needs triage
Request service download_chunks crashes with unhandled ChunkedEncodingError when a remote-build artifact download breaks mid-transfer, forcing a full rebuild. No retry logic exists in the code at HEAD; issue is unlabeled with no maintainer activity for ~7 months.
qwen/qwen3.6-35b-a3b
Staleness:
70
Complexity:
45
Confidence:
90
Support Request:
10
needs triage
Feature request to implement retry logic for broken network connections during artifact downloads. Issue is unlabelled, has zero maintainer comments, and has been inactive for over 6 months.
qwen3.6-35b-a3b-mtp-q6
Staleness:
75
Complexity:
40
Confidence:
90
Support Request:
10
needs triage
Request to implement retry logic for transient network errors during artifact downloads in craft_application. The issue is unlabelled, has zero comments, and has been inactive for 164 days.
qwen3.6-35b-a3b-mtp-q6
Staleness:
45
Complexity:
45
Confidence:
90
Support Request:
10
needs triage
Implement retry logic in the request module to handle ChunkedEncodingError from broken network connections during artifact downloads. Open for 142 days with zero comments, needs triage and assignment to improve CI stability.
Update history
No update history recorded yet.
Related issues
No related issues found above the similarity threshold.