publish.sh: stop awscli2 sending a checksum Garage rejects #4

Merged
claude merged 1 commits from fix/garage-checksum into main 2026-09-09 06:59:04 +00:00
Member

Closes #3.

publish.sh could not upload anything to Garage as merged in #2 — it would have failed on first real use, after passing its whole test suite.

Measured, not inferred

An error occurred (InvalidRequest) when calling the PutObject operation:
Bad request: invalid checksum algorithm

aws-cli/2.34.24. Recent awscli2 attaches a checksum algorithm to every PutObject by default; Garage refuses it.

The expensive part is that it reads as a permissions problem: reads succeed on every bucket, writes fail on every bucket, and it fails identically against one the same credentials are known to be able to write. I only separated the two by testing a bucket I knew was writable.

The fix

AWS_REQUEST_CHECKSUM_CALCULATION=when_required and AWS_RESPONSE_CHECKSUM_VALIDATION=when_required, set inside the script. A caller should not have to know about a client-side default to publish to the object store this tooling exists for, and leaving it to the environment means it works on one machine and not another. when_required keeps checksums where the protocol needs them, which is narrower than switching them off.

The test that would have caught it

An opt-in live round trip — upload, read back byte-for-byte, delete — skipped unless a scratch bucket and credentials are present, so the default offline run is unchanged.

Everything else in this suite proves the command is well formed. That is a different claim from a server accepts it, and this failure lived exactly in the gap.

One trap worth knowing about: the live block captures the real credentials at the top of the file, before the deliberate fakes (AKIAFAKETESTKEY) are exported for the offline tests. Without that it authenticates as the fake and fails every time — and a live test that always fails gets disabled, which is worse than not having one. That cost me a debugging round.

Verified both directions against the real bucket

passed skipped failed
offline 9 1 0
live 11 0 0
live, with the fix removed 9 0 2

The third row is the one that matters: the new test genuinely catches the original bug rather than merely passing alongside the fix.

Closes #3. `publish.sh` could not upload anything to Garage as merged in #2 — it would have failed on first real use, after passing its whole test suite. ## Measured, not inferred ``` An error occurred (InvalidRequest) when calling the PutObject operation: Bad request: invalid checksum algorithm ``` aws-cli/2.34.24. Recent awscli2 attaches a checksum algorithm to every `PutObject` by default; Garage refuses it. The expensive part is that **it reads as a permissions problem**: reads succeed on every bucket, writes fail on every bucket, and it fails identically against one the same credentials are known to be able to write. I only separated the two by testing a bucket I knew was writable. ## The fix `AWS_REQUEST_CHECKSUM_CALCULATION=when_required` and `AWS_RESPONSE_CHECKSUM_VALIDATION=when_required`, set **inside the script**. A caller should not have to know about a client-side default to publish to the object store this tooling exists for, and leaving it to the environment means it works on one machine and not another. `when_required` keeps checksums where the protocol needs them, which is narrower than switching them off. ## The test that would have caught it An **opt-in live round trip** — upload, read back byte-for-byte, delete — skipped unless a scratch bucket and credentials are present, so the default offline run is unchanged. Everything else in this suite proves the command is *well formed*. That is a different claim from *a server accepts it*, and this failure lived exactly in the gap. One trap worth knowing about: the live block captures the real credentials at the **top** of the file, before the deliberate fakes (`AKIAFAKETESTKEY`) are exported for the offline tests. Without that it authenticates as the fake and fails every time — and a live test that always fails gets disabled, which is worse than not having one. That cost me a debugging round. ## Verified both directions against the real bucket | | passed | skipped | failed | |---|---|---|---| | offline | 9 | 1 | 0 | | live | **11** | 0 | 0 | | live, with the fix removed | 9 | 0 | **2** | The third row is the one that matters: the new test genuinely catches the original bug rather than merely passing alongside the fix.
claude added 1 commit 2026-09-09 06:58:48 +00:00
Measured against the real endpoint, not inferred: every PutObject failed
with

    An error occurred (InvalidRequest) when calling the PutObject
    operation: Bad request: invalid checksum algorithm

on aws-cli/2.34.24. Recent awscli2 attaches a checksum algorithm by
default and Garage refuses it, so publish.sh could not upload anything --
after passing its entire test suite.

It also reads as a permissions problem, which is the expensive part: reads
succeed, writes fail, and it fails identically against a bucket the same
credentials demonstrably can write. Set here rather than documented,
because a caller should not need to know a client-side default to publish
to the object store this script exists for, and leaving it to the
environment makes it work on one machine and not another.
`when_required` keeps checksums where the protocol needs them, so this is
narrower than switching them off.

Adds the test that would have caught it: an opt-in live round trip that
uploads, reads back and deletes, skipped unless a scratch bucket and
credentials are present so the offline run is unchanged. Everything else in
this suite proves the command is well formed, which is a different claim
from a server accepting it, and this failure lived exactly in that gap.

The live block captures the real credentials at the top of the file,
before the deliberate fakes (AKIAFAKETESTKEY) are exported for the offline
tests -- otherwise it authenticates as the fake and fails every time, and a
live test that always fails gets disabled, which is worse than not having
one.

Verified both directions against the real bucket: with the fix, 11 passed /
0 skipped; with it removed, the two live assertions fail. Offline, 9 passed
/ 1 skipped.

Closes #3.

Co-authored-by: bit <bit@das-labor.org>
claude merged commit fcc6a741ef into main 2026-09-09 06:59:04 +00:00
claude deleted branch fix/garage-checksum 2026-09-09 06:59:05 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: weblib/fdroid-repo-ci#4