Repository navigation
SHA256SUMS.txt ships CRLF, so shasum -c fails on macOS and Linux #2383
Description
SHA256SUMS.txt ships with CRLF line endings, so shasum -c on macOS and Linux reports every Windows artifact as missing. The hashes are correct; the file just cannot be used with the standard tool on the platforms most likely to run it.
Found verifying the v3.5.0 release assets.
Reproduction
$ shasum -a 256 -c SHA256SUMS.txt
shasum: PerformanceMonitorDarling-3.5.0.zip: No such file or directory
PerformanceMonitorDarling-3.5.0.zip: FAILED open or read
shasum: PerformanceMonitorLite-3.5.0.zip: No such file or directory
PerformanceMonitorLite-3.5.0.zip: FAILED open or read
shasum: WARNING: 2 listed files could not be read
Both files are present in the directory. The trailing \r is part of the filename shasum -c goes looking for:
$ file SHA256SUMS.txt
SHA256SUMS.txt: ASCII text, with CRLF line terminators
$ head -1 SHA256SUMS.txt | xxd | tail -1
00000060: 302e 7a69 700d 0a 0.zip..
Strip the carriage returns and it verifies clean:
$ tr -d '\r' < SHA256SUMS.txt | shasum -a 256 -c -
PerformanceMonitorDarling-3.5.0.zip: OK
PerformanceMonitorLite-3.5.0.zip: OK
SHA256SUMS-linux.txt is unaffected — it is written by the Linux job and is LF, and verifies as published.
Why it is worth fixing rather than shrugging at
The artifacts are fine and the hashes are right, so nothing is actually broken about the release. But a checksum file exists for exactly one purpose, and this one fails at that purpose on the two platforms where shasum is the default tool. The failure mode is also the worst possible wording: FAILED open or read next to a download is what a tampered or truncated file looks like, so the honest reading of this output is "something is wrong with the release", which is the opposite of what a checksum is supposed to communicate.
Windows users are unaffected — Get-FileHash is compared by eye or by script, not by parsing this file — so this lands entirely on the Linux/macOS side, which is also where the linux-x64 tarball audience lives.
Fix
The step that writes SHA256SUMS.txt runs on windows-latest, so PowerShell's default redirection/Out-File gives CRLF. Writing it with explicit LF is a one-liner, e.g.
$lines = ... # "<hash> <filename>" strings
[IO.File]::WriteAllText($path, ($lines -join "`n") + "`n", [Text.UTF8Encoding]::new($false))WriteAllText with an explicit "n"` join avoids both the CRLF and a UTF-8 BOM — a BOM on the first line would break the first entry the same way, so worth handling in the same change.
Worth a test that reads the produced file back and asserts no \r and no BOM, since this is invisible on the machine that writes it.
Not urgent and not worth a re-release of 3.5.0 on its own; fold into whatever ships next.
Activity
Write SHA256SUMS.txt with LF so shasum -c works
Write SHA256SUMS.txt with LF so shasum -c works (#2384)
erikdarlingdata commentedon Aug 20, 2026
Fixed in #2384 (merged to dev) — auto-close did not fire because the PR targets
devrather than the default branch.SHA256SUMS.txtis now written with[IO.File]::WriteAllTextand an explicit LF join, which also avoids a BOM. Anchored on$PWDbecause[IO.File]::WriteAllTextresolves relative paths against .NET's current directory rather than PowerShell's location — the original bare relative path worked only becauseOut-Fileuses the latter, so swapping the API without that guard would have written the file somewhere else.Not verified yet, and cannot be by CI: the step is gated on
github.event_name == 'release', so it only runs when a release publishes. Whoever cuts the next release should actually runshasum -a 256 -c SHA256SUMS.txtagainst the published assets rather than assume it works. The v3.5.0 assets themselves are fine — the hashes were always correct, only the file's line endings were wrong.Point the release copy at its twin as well (#2383)
erikdarlingdata commentedon Aug 21, 2026
Reopening the record rather than the issue: this was closed by #2384, which fixed
build.ymland left the identical step innightly.yml. Every nightly between then and today published a checksum fileshasum -ccannot read.Verified on the artifact rather than the workflow:
and with the artifact present, so the failure is the CR and not a missing file — CRLF gives
FAILED open or read, LF givesOK.#2398 fixes the nightly and puts a cross-reference in both copies, since the defect was one being updated without the other. Now genuinely closed on both paths.
The nightly writes SHA256SUMS.txt with CRLF too (erikdarlingdata#2383)