Date bug in Rust-based coreutils affects Ubuntu 25.10 automatic updates

Bug and Root Cause

  • The issue was Ubuntu’s use of uutils’ Rust date as a drop‑in replacement for GNU date.
  • The -r/--reference option (print mtime of a file) was parsed but effectively ignored, falling back to “current time”.
  • This behavior dates back to the initial “partial implementation of date” in 2017: the flag was accepted, documented in --help, but never wired into the logic.
  • When Ubuntu’s update system used date -r to decide if updates were needed, it silently mis‑behaved and skipped automatic updates.

Testing, Maturity, and Responsibility

  • Upstream GNU coreutils had no test for date -r until after this incident; a new test was just added.
  • uutils explicitly does not yet pass the full GNU coreutils test suite; for date, several tests are still skipped or failing.
  • Many commenters argue Ubuntu should not have shipped this as the default coreutils until test coverage and behavior parity were much closer.
  • Some blame Canonical for rushing a core replacement without end‑to‑end tests of critical paths like system updates; others fault uutils for accepting unimplemented options without error.

Rust Culture, Stability, and Breaking Changes

  • A long sub‑thread argues over whether Rust has a “ready to break things on a whim” culture.
  • Critics point to Rust 1.80’s type‑inference change that broke existing crates (e.g. time) and caused pain for ecosystems like Nix, and to Cargo’s historic tendency to pull newest deps that might require a newer compiler.
  • Defenders counter that:
    • These changes were discussed and not “on a whim”.
    • Such breakages are rare and heavily scrutinized.
    • Compared to C/C++ compilers and GNU extensions, Rust’s overall stability focus is strong.
  • There is also debate over pre‑1.0 (0.x) crate versions and whether they actually signal instability or just version‑number conservatism.

Security vs Licensing Motives

  • Canonical’s public rationale: resilience and memory safety for core tools, not primarily performance.
  • Some commenters doubt the security payoff for low‑attack‑surface tools like date, and note that rewrites introduce new logic bugs anyway.
  • Others emphasize that coreutils do process untrusted data (files, checksums, encodings), so memory‑safe implementations are inherently valuable.
  • A separate line of discussion suspects licensing is key: GNU coreutils are GPLv3, while uutils is MIT, which is more comfortable for embedded and locked‑down devices.
    • Some see this as part of a broader trend away from GPLv3; others counter that Ubuntu still depends on GPLv3 components (e.g. libgcc) so this alone doesn’t free them.

Rewrites, Maintenance, and Ecosystem Impact

  • One camp views Rust rewrites of mature tools as “attention‑seeking” or “virtue signaling”, arguing effort should go to maintaining and verifying existing C code.
  • Another camp argues:
    • Rewrites uncover underspecified behavior and gaps in original test suites (as happened here).
    • Rust’s defaults and type system reduce entire classes of bugs compared to relying on optional static analysis in C.
    • New code in Rust may be more attractive to future maintainers than legacy C.
  • There is concern that fragmented rewrites (coreutils, sudo, etc.) increase compatibility risk in an ecosystem already rich in fragile shell scripts.

Ubuntu Release Strategy and Risk Tolerance

  • Some see using 25.10 (a non‑LTS release) as an acceptable testbed to shake out bugs before 26.04 LTS.
  • Others note that Canonical markets interim releases as “production‑quality”, so shipping incomplete coreutils there is still inappropriate.
  • Several users say this, combined with snaps and other disruptive changes, pushes them toward Debian or other “boring” distros.

Testing Techniques Going Forward

  • Suggestions include:
    • Differential testing/fuzzing against GNU coreutils as an oracle.
    • Property‑based testing or Hypothesis‑style generators driving both implementations.
    • Static checks or argument‑parsing frameworks that reject recognized‑but‑unused options instead of silently ignoring them.