Symptom: spikersoft-backend ArtPipeProcessor build_and_publish (run 11507 / job 41850, triggered by the #767 messaging merge but unrelated to it) fails all 5 env-image pull attempts with unexpected EOF on layer f88a4842bed8 of artpipe-model-env-prodstages:latest. create_manifest failed downstream. Every future master push touching the artpipe paths will fail the same way.
Diagnosis (2026-07-21 ~05:30 UTC):
MinIO and Gitea are both healthy — no crash-loop, no restarts since 07-18 18:30, disk 11% used. This is NOT a repeat of #700's outage mode.
The failing layer blob is 17,250,041,544 bytes. Direct curl of the blob dies at byte ~534,770,000 (±2 KB) on every attempt regardless of elapsed time (43–65s) → deterministic offset, not a timeout.
Reading the object directly from MinIO (mc cat on SERVER against gitea-packages/packages/f8/8a/f88a4842…) dies at the same offset: 534,773,760 bytes = exactly inside part.32 of the 1029-part multipart object (16 MiB parts). mc stat reports the full 16 GiB; all 1029 part files exist on disk (16.8 GB). MinIO aborts the stream at part 32 → integrity/bitrot verification failure on that part. Object was pushed 2026-07-19 15:49 UTC while MinIO was stably up, so the part was either written bad or rotted at rest on the fioa drive.
Compounding Gitea defect: the container registry blob endpoint ignores Range headers (returns 200 from byte 0, not 206), so docker's layer-resume retries always restart from zero and hit the same wall — retries can never help.
Impact:artpipe-model-env-prodstages:latest is unpullable by any node that doesn't already have the layer (no build node has it cached — 4090/laptop-server/SERVER all checked). Tier-3 prodstages builds are blocked until the env image is republished.
Remediation:
Re-run spikersoft-artpipe → ModelEnvImages via workflow_dispatch with images: prodstages (its designed rebuild path; it cascade-dispatches the backend ArtPipeProcessor workflow on success). Fresh layers get new digests, so the corrupt blob is simply bypassed; it becomes orphaned garbage for Gitea's package cleanup.
Afterwards re-run the failed backend job (or let the next master push do it).
Consider a sweep of other recent large gitea-packages blobs for the same silent corruption (read-verify, not just stat).
Systemic notes: third MinIO-single-node incident class (#700 Gitea registry hard-depends on MinIO; #696 MinIO SPOF discussion; #413 storage epic) — single-drive MinIO detects bitrot but cannot heal it. Erasure-coded multi-drive/node MinIO would have healed this transparently.
**Symptom:** spikersoft-backend ArtPipeProcessor `build_and_publish` (run 11507 / job 41850, triggered by the #767 messaging merge but unrelated to it) fails all 5 env-image pull attempts with `unexpected EOF` on layer `f88a4842bed8` of `artpipe-model-env-prodstages:latest`. `create_manifest` failed downstream. Every future master push touching the artpipe paths will fail the same way.
**Diagnosis (2026-07-21 ~05:30 UTC):**
- MinIO and Gitea are both healthy — no crash-loop, no restarts since 07-18 18:30, disk 11% used. This is NOT a repeat of #700's outage mode.
- The failing layer blob is 17,250,041,544 bytes. Direct curl of the blob dies at byte ~534,770,000 (±2 KB) on every attempt regardless of elapsed time (43–65s) → deterministic offset, not a timeout.
- Reading the object directly from MinIO (`mc cat` on SERVER against `gitea-packages/packages/f8/8a/f88a4842…`) dies at the same offset: 534,773,760 bytes = exactly inside part.32 of the 1029-part multipart object (16 MiB parts). `mc stat` reports the full 16 GiB; all 1029 part files exist on disk (16.8 GB). MinIO aborts the stream at part 32 → integrity/bitrot verification failure on that part. Object was pushed 2026-07-19 15:49 UTC while MinIO was stably up, so the part was either written bad or rotted at rest on the fioa drive.
- **Compounding Gitea defect:** the container registry blob endpoint ignores `Range` headers (returns 200 from byte 0, not 206), so docker's layer-resume retries always restart from zero and hit the same wall — retries can never help.
**Impact:** `artpipe-model-env-prodstages:latest` is unpullable by any node that doesn't already have the layer (no build node has it cached — 4090/laptop-server/SERVER all checked). Tier-3 prodstages builds are blocked until the env image is republished.
**Remediation:**
1. Re-run `spikersoft-artpipe` → `ModelEnvImages` via workflow_dispatch with `images: prodstages` (its designed rebuild path; it cascade-dispatches the backend ArtPipeProcessor workflow on success). Fresh layers get new digests, so the corrupt blob is simply bypassed; it becomes orphaned garbage for Gitea's package cleanup.
2. Afterwards re-run the failed backend job (or let the next master push do it).
3. Consider a sweep of other recent large `gitea-packages` blobs for the same silent corruption (read-verify, not just stat).
**Systemic notes:** third MinIO-single-node incident class (#700 Gitea registry hard-depends on MinIO; #696 MinIO SPOF discussion; #413 storage epic) — single-drive MinIO detects bitrot but cannot heal it. Erasure-coded multi-drive/node MinIO would have healed this transparently.
Resolved (2026-07-21 ~08:30 UTC). Recovery executed per remediation plan:
Dispatched ModelEnvImages (images: prodstages) in spikersoft-artpipe → success. New 17.25 GB layer has fresh digest c84d8ce56a2d…, replacing corrupt f88a4842bed8… (which is now orphaned pending package cleanup). The 15.7 GB sibling layer 8ab5954… kept its digest — it was never damaged.
Cascade auto-dispatched spikersoft-backend ArtPipeProcessor: build_and_publish → deploy → notify all green; rebuilt processor image deployed to the swarm.
Read-verified the replacement blob: streamed all 17,250,040,045 bytes from the registry and SHA-256 of the stream matches the digest exactly — no silent corruption this time (the 07-19 push looked "successful" too, hence the explicit check).
Remaining open items from this ticket:
Sweep other recent large gitea-packages blobs with the same read-verify (a "successful push" is demonstrably not proof of a readable blob).
Gitea registry ignores Range on blob GETs (200-from-zero, never 206) — makes docker layer-resume useless against any future flaky/corrupt blob; consider upstream issue.
Systemic: single-drive MinIO detects bitrot but cannot heal (#413/#696/#700 context).
**Resolved (2026-07-21 ~08:30 UTC).** Recovery executed per remediation plan:
1. Dispatched `ModelEnvImages` (`images: prodstages`) in spikersoft-artpipe → success. New 17.25 GB layer has fresh digest `c84d8ce56a2d…`, replacing corrupt `f88a4842bed8…` (which is now orphaned pending package cleanup). The 15.7 GB sibling layer `8ab5954…` kept its digest — it was never damaged.
2. Cascade auto-dispatched spikersoft-backend ArtPipeProcessor: build_and_publish → deploy → notify all green; rebuilt processor image deployed to the swarm.
3. **Read-verified the replacement blob**: streamed all 17,250,040,045 bytes from the registry and SHA-256 of the stream matches the digest exactly — no silent corruption this time (the 07-19 push looked "successful" too, hence the explicit check).
Remaining open items from this ticket:
- Sweep other recent large `gitea-packages` blobs with the same read-verify (a "successful push" is demonstrably not proof of a readable blob).
- Gitea registry ignores `Range` on blob GETs (200-from-zero, never 206) — makes docker layer-resume useless against any future flaky/corrupt blob; consider upstream issue.
- Systemic: single-drive MinIO detects bitrot but cannot heal (#413/#696/#700 context).
Incident resolved same-day (rebuild + cascade + full read-back verification — see resolution comment above). Systemic follow-ups consolidated with #720's into #776 now that this is a RECURRING class (2 incidents in 3 days). Closing the incident ticket.
Incident resolved same-day (rebuild + cascade + full read-back verification — see resolution comment above). Systemic follow-ups consolidated with #720's into #776 now that this is a RECURRING class (2 incidents in 3 days). Closing the incident ticket.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Symptom: spikersoft-backend ArtPipeProcessor
build_and_publish(run 11507 / job 41850, triggered by the #767 messaging merge but unrelated to it) fails all 5 env-image pull attempts withunexpected EOFon layerf88a4842bed8ofartpipe-model-env-prodstages:latest.create_manifestfailed downstream. Every future master push touching the artpipe paths will fail the same way.Diagnosis (2026-07-21 ~05:30 UTC):
mc caton SERVER againstgitea-packages/packages/f8/8a/f88a4842…) dies at the same offset: 534,773,760 bytes = exactly inside part.32 of the 1029-part multipart object (16 MiB parts).mc statreports the full 16 GiB; all 1029 part files exist on disk (16.8 GB). MinIO aborts the stream at part 32 → integrity/bitrot verification failure on that part. Object was pushed 2026-07-19 15:49 UTC while MinIO was stably up, so the part was either written bad or rotted at rest on the fioa drive.Rangeheaders (returns 200 from byte 0, not 206), so docker's layer-resume retries always restart from zero and hit the same wall — retries can never help.Impact:
artpipe-model-env-prodstages:latestis unpullable by any node that doesn't already have the layer (no build node has it cached — 4090/laptop-server/SERVER all checked). Tier-3 prodstages builds are blocked until the env image is republished.Remediation:
spikersoft-artpipe→ModelEnvImagesvia workflow_dispatch withimages: prodstages(its designed rebuild path; it cascade-dispatches the backend ArtPipeProcessor workflow on success). Fresh layers get new digests, so the corrupt blob is simply bypassed; it becomes orphaned garbage for Gitea's package cleanup.gitea-packagesblobs for the same silent corruption (read-verify, not just stat).Systemic notes: third MinIO-single-node incident class (#700 Gitea registry hard-depends on MinIO; #696 MinIO SPOF discussion; #413 storage epic) — single-drive MinIO detects bitrot but cannot heal it. Erasure-coded multi-drive/node MinIO would have healed this transparently.
Resolved (2026-07-21 ~08:30 UTC). Recovery executed per remediation plan:
ModelEnvImages(images: prodstages) in spikersoft-artpipe → success. New 17.25 GB layer has fresh digestc84d8ce56a2d…, replacing corruptf88a4842bed8…(which is now orphaned pending package cleanup). The 15.7 GB sibling layer8ab5954…kept its digest — it was never damaged.Remaining open items from this ticket:
gitea-packagesblobs with the same read-verify (a "successful push" is demonstrably not proof of a readable blob).Rangeon blob GETs (200-from-zero, never 206) — makes docker layer-resume useless against any future flaky/corrupt blob; consider upstream issue.Incident resolved same-day (rebuild + cascade + full read-back verification — see resolution comment above). Systemic follow-ups consolidated with #720's into #776 now that this is a RECURRING class (2 incidents in 3 days). Closing the incident ticket.
Correction: the consolidated hardening ticket is #775 (not #776).