[2026-09-10 20:36:02] verify-lock ERROR: R2 PUT db/daily/lock-verify-20260910-123602.txt returned HTTP 400 — InvalidArgument
[2026-09-10 21:07:01] DIAGNOSE: credential file shape (no secrets are printed).
[2026-09-10 21:07:01]   line 1  Cloudflare account id  32 chars, hex          looks right
[2026-09-10 21:07:01]   line 2  R2 Access Key ID       53 chars, alnum/-_.    <<< UNEXPECTED SHAPE (expected 32 hex characters)
[2026-09-10 21:07:01]   line 3  Secret Access Key      64 chars, hex          looks right
[2026-09-10 21:07:01]   line 4  bucket name            14 chars, alnum/-_.    looks right
[2026-09-10 21:07:01]   NOTE: R2 shows THREE strings when a token is created — "Token value",
[2026-09-10 21:07:01]   "Access Key ID" and "Secret Access Key". Line 2 must be the Access Key ID
[2026-09-10 21:07:01]   (32 hex), NOT the token value. Line 1 is the account id from the R2 page.
[2026-09-10 21:07:01]   PUT UNLOCKED prefix          -> HTTP 400  :: InvalidArgument: Credential access key has length 53, should be 32
[2026-09-10 21:07:01]   PUT LOCKED prefix db/daily/  -> HTTP 400  :: InvalidArgument: Credential access key has length 53, should be 32
[2026-09-10 21:07:01] DIAGNOSE complete. Both failing the same way = credential/client fault, not the lock.
[2026-09-10 21:08:01] DIAGNOSE: credential file shape (no secrets are printed).
[2026-09-10 21:08:01]   line 1  Cloudflare account id  32 chars, hex          looks right
[2026-09-10 21:08:01]   line 2  R2 Access Key ID       53 chars, alnum/-_.    <<< UNEXPECTED SHAPE (expected 32 hex characters)
[2026-09-10 21:08:01]   line 3  Secret Access Key      64 chars, hex          looks right
[2026-09-10 21:08:01]   line 4  bucket name            14 chars, alnum/-_.    looks right
[2026-09-10 21:08:01]   NOTE: R2 shows THREE strings when a token is created — "Token value",
[2026-09-10 21:08:01]   "Access Key ID" and "Secret Access Key". Line 2 must be the Access Key ID
[2026-09-10 21:08:01]   (32 hex), NOT the token value. Line 1 is the account id from the R2 page.
[2026-09-10 21:08:01]   PUT UNLOCKED prefix          -> HTTP 400  :: InvalidArgument: Credential access key has length 53, should be 32
[2026-09-10 21:08:02]   PUT LOCKED prefix db/daily/  -> HTTP 400  :: InvalidArgument: Credential access key has length 53, should be 32
[2026-09-10 21:08:02] DIAGNOSE complete. Both failing the same way = credential/client fault, not the lock.
[2026-09-10 21:28:02] verify-lock: marker stored at db/daily/lock-verify-20260910-132801.txt.
[2026-09-10 21:28:02] verify-lock: DELETE answered HTTP 409 :: ObjectLockedByBucketPolicy: The object is locked by the bucket policy.; the marker SURVIVED.
[2026-09-10 21:28:02] verify-lock PASS: the object is still there after a delete attempt with the host's own credential (HTTP 409) — the bucket lock is enforcing.
[2026-09-10 21:50:01] START: off-host backup to R2 bucket `kualifi-backup`.
[2026-09-10 21:50:02] dump: stored db/daily/kualifi-2026-09-10.sql.gz (40,650 B gzipped).
[2026-09-10 21:50:02] dump: first of the month — also stored db/monthly/kualifi-2026-09.sql.gz.
[2026-09-10 21:50:02] evidence: 0 row(s), 0 distinct object(s) confirmed in R2 (0 uploaded now), 0 missing locally, 0 failed, 0 without sha256.
[2026-09-10 21:50:02] DONE: backup healthy.
[2026-09-11 03:30:05] START: off-host backup to R2 bucket `kualifi-backup`.
[2026-09-11 03:30:05] dump: stored db/daily/kualifi-2026-09-11.sql.gz (40,701 B gzipped).
[2026-09-11 03:30:06] evidence: 0 row(s), 0 distinct object(s) confirmed in R2 (0 uploaded now), 0 missing locally, 0 failed, 0 without sha256.
[2026-09-11 03:30:06] DONE: backup healthy.
