Ubuntu 25.10's Rust Coreutils Is Causing Major Breakage for Some Executables
Mood
heated
Sentiment
negative
Category
other
Key topics
Ubuntu
Rust
Coreutils
Ubuntu 25.10's adoption of Rust Coreutils is causing breakage for some executables, sparking debate about the readiness of Rust Coreutils and its implications for the Linux ecosystem.
Snapshot generated from the HN discussion
Discussion Activity
Very active discussionFirst comment
17m
Peak period
74
Day 1
Avg / period
15.8
Based on 79 loaded comments
Key moments
- 01Story posted
Sep 26, 2025 at 12:04 PM EDT
2 months ago
Step 01 - 02First comment
Sep 26, 2025 at 12:21 PM EDT
17m after posting
Step 02 - 03Peak activity
74 comments in Day 1
Hottest window of the conversation
Step 03 - 04Latest activity
Oct 6, 2025 at 4:02 PM EDT
about 2 months ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
But it actually appears to be an issue with dd, not md5sum - https://github.com/VirtualBox/virtualbox/issues/226#issuecom...
The bs/ibs/obs options don't "skip" anything, but determine how much data to buffer in memory at a time while transferring. Regardless, it's hard to fathom how something this simple got messed up, especially considering that the suite supposedly has good test coverage and has been getting close to a full green bar.
so it is a bug. bs is one thing, ibs is another.
bs=BYTES
read and write up to BYTES bytes at a time (default: 512); over‐
rides ibs and obs
As described, the script should have worked as is, and the problem is in the handling of the dd options. (But I didn't verify the accuracy of the description.)echo -e "\00" | md5sum 8f7cbbbe0e8f898a6fa93056b3de9c9c -
echo -e "\00\00" | md5sum a4dd23550d4586aee3b15d27b5cec433 -
`dd` is for copying all the bytes of a source (unless you explicitly set a limit with the `count` option), regardless of whether they're zero. It's fundamentally not for null-terminated strings but arbitrary binary I/O. In fact, "copying from" /dev/zero is a common use case. It seems frankly implausible that the `dd` implementation is just stopping at a null byte; that would break a lot of tests and demonstrate a complete, fundamental misunderstanding of what's supposed to be implemented.
> Not sure how to run the rust version but my md5sum seems to care how many null bytes there are.
Yes, the md5 algorithm also fundamentally operates on and produces binary data; `md5sum` just converts the bytes to a hex dump at the end. The result you get is expected (edit: modulo hiccuphippo's correct observation), because the correct md5 sum changes with every byte of input, even if that byte has a zero value.
Add -n to echo to avoid the new line.
Only among those that don't understand that, if this is a problem, then it is Canonical problem, not a Rust problem.
To give another example, Canonical includes ZFS in Ubuntu too. And, for a while, Canonical shipped a broken snapshot mechanism called zsys with Ubuntu too. Canonical ultimately ripped zsys out because it didn't work very well. zsys would choke on more than 4000 snapshots, etc. zsys was developed in Go, while other snapshot systems developed in Perl and Python did a little less and worked better.
Now, is zsys a Go problem? Of course not. It wasn't ready because Canonical sometimes ships broken stuff.
(This is hard to express in a careful way where I'm confident of not offending anyone. Please take me at my word that I'm not trying to take sides in this at all.)
The dominant narrative behind this pushback, as far as I can tell, is nothing to do with the Rust language itself (aside perhaps from a few fringe people who see the adoption of Rust as some kind of signal of non-programming-related politics, and who are counter-signaling). Rather, the opposition is to re-implementing "working" software (including in the sense that nobody seems to have noticed any memory-handling faults all this time) for the sake of seemingly nebulous benefits (like compiler-checked memory safety).
The Rust code will probably also be more maintainable by Rust developers than the C code currently is by C developers given the advantages of Rust's language design. (Unless it turns out that the C developers are just intrinsically better at programming and/or software engineering; I'm pretty skeptical of that.) But most long-time C users are probably not going to want to abandon their C expertise and learn Rust. And they seem to outnumber the new Rust developers by quite a bit, at least for now.
Difficult to say with certainty, because it's easy to dress "political" resistance in respectable preference for stability. (Scare quotes because it's an amalgam in which politics is just a part.) Besides, TFA is Phoronix, whose commentariat is not known for subtlety on this topic.
Replacing coreutils is risky because of the decades of refinement/stagnation (depending on your viewpoint) which will inevitably produce snags when component utilities interact in ways unforeseen by tests -- as has happened here. But without risk there's no reward. Of course, what's the reward here is subject to debate. IMO the self-evident advantage of a rewrite is that it's prima facie evidence of interest in using the language, which is significant if there's a dearth of maintainers for the originals. (The very vocal traditionalists are usually not in a hurry to contribute.)
I understand the argument, and its sounds good as far as most things go, but it misses an important fact: In OSS, you can and should find your own bliss. If you want to learn Rust, as I did, you can do it by reimplementing uutils' sort and ls, and fixing bugs in cp and mv, as I did. That was my bliss. OSS doesn't need to be useful to anyone. OSS can be a learning exercise or it can be simply for love of the game.
The fact that Canonical wants to ship it, right now, simply makes them a little silly. It doesn't say a thing about me, or Rust, or Rust culture.
If you can afford it, sure. Some would really prefer to at least be able to get some attention (and perhaps a paid job) this way.
Not that I agree, but people seem to be giving uutils lots of attention right now? A. HN front page vs. B. obscure JS framework? I'll take door "A"?
I had someone contact me for a job simply because my Rust personal project had lots of stars on Github. You really don't know what people will find interesting.
Because X11 had a lot of issues that got papered over with half-baked extensions and weird interfaces to the kernel.
The problem is that Wayland didn't feel like doing the work to make fundamental things like screen sharing, IMEs, copy-paste, and pointer warping actually ... you know ... work.
The problem Wayland now has is that they're finally reaching something usable, but they took so long that the assumptions they made nearly 20 years ago are becoming as big a problem as the issues that were plaguing X11 when Wayland started. However, the sunk cost fallacy means that everybody going to keep pounding on Wayland rather than throwing it out and talking to graphics cards directly.
And client rendered decorations was always just a mind bogglingly stupid decision--but that's a Gnome problem rather than a Wayland issue.
Rust is trying to systemically improve safety and reliability of programs, so the degree to which it succeeds is Rust's problem.
OTOH we also have people interpreting it as if Rust was supposed to miraculously prevent all bugs, and they take any bug in any Rust program as a proof by contradiction that Rust doesn't work.
Isn't that an unfalsifiable statement until the coreutils get written in another language and can be compared?
Sounds pretty axiomatic: Rust is not to blame for someone else's choice to ship beta software?
GNU coreutils first shipped in what, the 1980s? It's so old that it would be very hard to find the first commit. Whereas uutils is still beta software which didn't ask to be representative of "Rust", at all. Moreover, GNU coreutils are still sometimes not compatible with their UNIX forebears. Even considering this first, more modest standard, it is ridiculous to hold this software to it, in particular.
I don't mean to tell Rust uutils authors not to write a project they wanted, but I don't see why Canonical was so eager to switch, given that there are non-zero switching costs for others.
If anyone has original Fileutils, Shellutils, or Textutils archives (released before the ones currently on GNU's ftp server), I would be interested in looking at them. I looked into this recently for a commit [1].
[1] https://www.mail-archive.com/coreutils@gnu.org/msg12529.html
That is the narative that rust fanboys promote. AFAIK rust could be usefull for a particular kind of bugs (memory safety). Rust programs can also have coding errors or other bugs.
Strawmanning is not a good look.
Yeah, that's such a tired take. If anything this shows how good Rust's guarantees are. We had a bunch of non-experts rewrite a sizable number of tools that had 40 years of bugfixes applied. And Canonical just pulled the rewritten versions in all at once and there are mostly a few performance regressions on edge cases.
I find this such a great confirmation of the Rust language design. I've seen a few rewrites in my career, and it rarely goes this smoothly.
Does this have anything at all to do with the kernel?
There are plenty of ecosystems where programs declare a specific library implementation they expect to call into (Rust, Python, Npm, Ruby, Perl, ...) often even constrained by versions. But also if you depend on libcurl you are only going to have to deal with multiple verions of the same implementation (that you can still constrain in e.g. pkg-config).
In shell scripting you have to deal with stuff like "in nc, EOF on stdin is undefined behavior and implementation specific".
"Interim releases will introduce new capabilities from Canonical and upstream open source projects, they serve as a proving ground for these new capabilities." https://ubuntu.com/about/release-cycle
I don't follow, can you explain why?
1. This is an inevitable problem that is being handled in a sensible manner by competent engineers.
2. X company is stupid and their engineers are stupid only someone as smart as I would be capable of doing it right
It tells a lot about the mental maturity of each participant. Not a single comment is "Maybe I don't know enough about this to voice an informed opinion", although that's probably a good indiucator.
Survivorship bias.
https://www.phoronix.com/forums/forum/phoronix/latest-phoron...
Where it seems like text based forums using upvotes/likes or reactions encourages those who are less inquisitive and/or humble to take up a lot of the atmosphere.
It got me thinking that the internet today has more people on it but fewer forums to engage with technical topics in depth.
With a sufficient number of users of an API,
it does not matter what you promise in the contract:
all observable behaviors of your system
will be depended on by somebody.Never mind.
That is not a quote from that post. I am very much not pedantic about only using quotation marks for quotes as long as it reasonably accurately gets the gist right, but in this case it very much doesn't.
You are leaving out the qualified language of "generally", which completely changes what was said. And worse, the post explicitly acknowledges that it doesn't solve all bugs in the next sentence.
And even if you can dig deep and find someone using unqualified language somewhere, I'm willing to bet a lot of money that this is an oversight and when pressed they will immediately admit so (on account of this being an internet forum and not a scientific paper, and people are careless sometimes). "I like coffee" rarely means "I always like coffee, all the time, without exception".
Writing bugs in Rust is trivial and happens all the time. "do_stuff(sysv[1], sysv[2])" is a bug if you reversed the sysv arguments by accident. You can easily create a more complex version of that with a few "if" conditionals and interaction with other flags.
There are many such silly things people can – and do – trivially get wrong all the time. Most bugs I've written are of the "I'm a bloody idiot"-type. The only way to have a fool-proof compiler is to know intent.
What people may say is something like "if it compiles, then it runs", which is generally true, but doesn't mean it does the right thing (i.e. is free of bugs).
At any rate, small teething issues aside, long-term things should be better and faster.
GNU Coreutils uses the OpenSSL implementation of hashes by default, but some distributions have disabled it using './configure --with-openssl=no'. Debian used to do this, but now links to OpenSSL.
$ ldd /usr/bin/cksum
linux-vdso.so.1 (0x00007fb354763000)
libc.so.6 => /usr/lib64/libc.so.6 (0x00007fb354549000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fb354765000)
For context, I am a committer to GNU Coreutils. We have used OpenSSL by default for a few years now [1]. Previously it was disabled by default because the OpenSSL license is not compatible with the GPL license [2]. This was resolved when they switched to the Apache License, Version 2.0 in OpenSSL 3.0.0.If the Void people wanted to enable OpenSSL, they would probably just need to add openssl (or whatever they package it as) to the package dependencies.
[1] https://github.com/coreutils/coreutils/commit/0d77e1b7ea2840... [2] https://www.gnu.org/licenses/license-list.html#OpenSSL
I also have an Arch machine where it does link to libcrypto, and it seems roughly identical (or close enough that I don't care, this is a live server doing tons of $stuff so has big error bars):
md5sum 1.58s user 0.31s system 98% cpu 1.908 total
~/verify -a md5 1.59s user 0.13s system 99% cpu 1.719 total
sha256sum 0.71s user 0.12s system 99% cpu 0.840 total
~/verify -a sha256 0.74s user 0.12s system 99% cpu 0.862 total
Still wish it could do multi-core though; one reason I looked in to this is because I wanted to check 400G of files and had 15 cores doing nothing (I know GNU parallel exists, but I find it hard to use and am never quite sure I'm using it correctly, so it's faster to write my own little Go program – especially for verifying files). $ dd if=/dev/random of=input bs=1000 count=$(($(echo 10G | numfmt --from=iec) / 1000))
10737418+0 records in
10737418+0 records out
10737418000 bytes (11 GB, 10 GiB) copied, 86.3693 s, 124 MB/s
$ time ./src/sha256sum-libcrypto input
b3e702bb55a109bc73d7ce03c6b4d260c8f2b7f404c8979480c68bc704b64255 input
real 0m16.022s
$ time ./src/sha256sum-nolibcrypto input
b3e702bb55a109bc73d7ce03c6b4d260c8f2b7f404c8979480c68bc704b64255 input
real 0m39.339s
Perhaps there is something wrong with the detection on your system? As in, you do not have this at the end of './configure': $ grep -F 'HAVE_OPENSSL_' lib/config.h
#define HAVE_OPENSSL_MD5 1
#define HAVE_OPENSSL_MD5_H 1
#define HAVE_OPENSSL_SHA1 1
#define HAVE_OPENSSL_SHA256 1
#define HAVE_OPENSSL_SHA3 1
#define HAVE_OPENSSL_SHA512 1
#define HAVE_OPENSSL_SHA_H 1I thought I remember Go having pretty optimized assembly for crypto routines. But I have not used the language much. If you have your source code uploaded somewhere I'd be interested to have a look to see what I am missing out on.
https://github.com/uutils/coreutils/issues/8033
The other one was an edge-case with dangling symlinks:
https://github.com/uutils/coreutils/issues/8044
Both got fixed promptly, after taking the time to report them properly. :)
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.