How a NoMachine Update Nuked My Desktop (Twice)
A single config file can turn your Linux desktop into an expensive paperweight. Here's how NoMachine's bundled libraries broke my system and how to fix it.
Today I learned that a single config file can turn your Linux desktop into an expensive paperweight. Twice. In the same day.
The Setup
I run NoMachine on my main workstation for remote access. It’s been rock solid for years - fire up the client from my laptop, connect to my desktop, and I’ve got a full graphical session. Great for those “I’m on the couch but need to check something” moments.
Yesterday I updated NoMachine to the latest version. This morning, I tried to run sudo apt update and got:
sudo: account validation failure, is your account locked?
Weird. Let me try su:
su: Authentication failure
SSH? Dead. Even trying to log in from a TTY failed. Every single authentication mechanism on my system was broken.
Down the Rabbit Hole
After some frantic Googling from my phone, I discovered the culprit: NoMachine bundles its own version of libcrypt.so.1 and adds /usr/NX/lib to the system’s library search path via /etc/ld.so.conf.d/nomachine.conf.
The problem? NoMachine’s libcrypt is ancient and doesn’t have the XCRYPT_2.0 symbols that modern Linux expects. Every SUID binary (sudo, su, passwd, login) tries to load libcrypt for PAM authentication, gets the NoMachine version, and crashes.
The cruel irony: you can’t fix this with sudo because sudo is broken. You can’t su to root. You can’t even log in via TTY. The system has locked you out of fixing the system.
First Recovery Attempt
I booted from my Pop!_OS recovery USB, mounted the root partition, and surgically removed the offending library:
sudo mount /dev/nvme1n1p3 /mnt
sudo rm /mnt/usr/NX/lib/libcrypt.so.1
sudo umount /mnt
sudo reboot
The system booted. GDM started. I typed my password and…
“Oh no! Something has gone wrong”
The GNOME crash screen. That cheerful message that tells you absolutely nothing about what went wrong.
It Gets Worse
I tried Ctrl+Alt+F2 for a TTY. Black screen. Nothing.
At this point I’m staring at an unresponsive machine, wondering if I somehow made it worse. The previous Claude Code session (running on the recovery USB) had fixed the libcrypt issue - sudo should work now, right?
I rebooted to the recovery USB again, but this time I did something smarter: I installed SSH on the live environment and connected from a VM on my Proxmox server. Now I could actually dig in properly.
The Real Problem
Here’s what I found when I checked the library cache:
$ sudo chroot /mnt ldconfig -p | grep "/usr/NX" | head -10
libz.so => /usr/NX/lib/libz.so
libstdc++.so.6 => /usr/NX/lib/libstdc++.so.6
libssl.so => /usr/NX/lib/libssl.so
libX11.so.6 => /usr/NX/lib/libX11.so.6
libglib-2.0.so => /usr/NX/lib/libglib-2.0.so
...
Over 100 libraries from /usr/NX/lib were overriding system libraries. I had removed libcrypt, but nomachine.conf was still there, still telling the dynamic linker to prefer NoMachine’s bundled libraries.
GNOME Shell was trying to start with NoMachine’s ancient libstdc++.so.6. GTK was loading NoMachine’s libglib-2.0.so. X11 applications were using NoMachine’s libX11.so.6. Everything was broken.
The Actual Fix
The fix was embarrassingly simple:
sudo rm /mnt/etc/ld.so.conf.d/nomachine.conf
sudo chroot /mnt ldconfig
Two commands. Remove the config file that adds NoMachine’s library path, rebuild the cache. That’s it.
After rebooting, my desktop came up perfectly. All services running. Everything works.
Lessons Learned
Removing a single conflicting library isn’t enough. If a package adds its library path to
ld.so.conf.d, ALL its libraries will override system libraries. You have to remove the config file entirely.Having SSH access from another machine is invaluable. When your desktop is unbootable, being able to SSH in from a VM and poke around is a lifesaver. Install
openssh-serveron your live USB, set a password, and connect from anywhere on your network.NoMachine’s approach is fundamentally broken. They bundle libraries for “compatibility,” but those libraries conflict with modern system versions. The right approach would be to set
LD_LIBRARY_PATHonly for NoMachine processes, not add their path to the system-wideld.so.conf.d.Create an immutable blocker file. After fixing this, I ran:
sudo touch /etc/ld.so.conf.d/nomachine.conf sudo chattr +i /etc/ld.so.conf.d/nomachine.confNow NoMachine can’t recreate the file on future updates.
Quick Reference
If you hit this issue, here’s the TL;DR:
From a live USB:
sudo mount /dev/YOUR_ROOT_PARTITION /mnt
sudo rm /mnt/etc/ld.so.conf.d/nomachine.conf
sudo chroot /mnt ldconfig
sudo umount /mnt
sudo reboot
If you still have sudo access:
sudo rm /etc/ld.so.conf.d/nomachine.conf
sudo ldconfig
NoMachine will still work - it sets LD_LIBRARY_PATH for its own processes, so removing the system-wide config only affects other applications.
Final Thoughts
This bug has apparently been around for a while, affecting anyone who updates NoMachine on a modern Linux distro. The combination of bundled libraries and system-wide library path injection is a recipe for disaster.
I’ve documented the full technical details in a separate troubleshooting guide, but hopefully this post saves someone else a few hours of head-scratching. And maybe convinces the NoMachine developers to stop polluting the system library path.
Now if you’ll excuse me, I need to go set up some monitoring to alert me if nomachine.conf ever reappears.