Skip to content

SHA256SUMS.txt ships CRLF, so shasum -c fails on macOS and Linux #2383

Closed

Description

@erikdarlingdata

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

  1. added 2 commits that reference this issue on Aug 20, 2026
    03c53f8
    d34d1aa
  2. erikdarlingdata commented on Aug 20, 2026

    @erikdarlingdata
    OwnerAuthor

    Fixed in #2384 (merged to dev) — auto-close did not fire because the PR targets dev rather than the default branch.

    SHA256SUMS.txt is now written with [IO.File]::WriteAllText and an explicit LF join, which also avoids a BOM. Anchored on $PWD because [IO.File]::WriteAllText resolves relative paths against .NET's current directory rather than PowerShell's location — the original bare relative path worked only because Out-File uses 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 run shasum -a 256 -c SHA256SUMS.txt against 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.

  3. erikdarlingdata commented on Aug 21, 2026

    @erikdarlingdata
    OwnerAuthor

    Reopening the record rather than the issue: this was closed by #2384, which fixed build.yml and left the identical step in nightly.yml. Every nightly between then and today published a checksum file shasum -c cannot read.

    Verified on the artifact rather than the workflow:

    $ file nightly_SHA256SUMS.txt
    ASCII text, with CRLF line terminators
    
    $ head -1 nightly_SHA256SUMS.txt | cat -v
    f27860c5...  PerformanceMonitorDarling-3.5.0-nightly.20260821.zip^M
    

    and with the artifact present, so the failure is the CR and not a missing file — CRLF gives FAILED open or read, LF gives OK.

    #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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions