NixOS Generations: Making a Broken System Update a Rollback, Not an Outage
NixOS makes a bad configuration change recoverable by keeping the previous system generation bootable. Here is how generations work, a worked SSH/user example, and the limits of rollback.
08 Jul 2026, 16:12 UTC

The failure mode that makes generations worth the learning curve
You edit a system config, run an update, reboot, and the machine comes up without networking or a display manager. On a conventional Linux distribution, recovery often means booting a rescue image, chrooting, and reversing package transactions by hand. On NixOS, the previous system generation is still present and bootable. That difference is the practical reason to care about NixOS generations, not declarative configuration as an abstract ideal.
The thesis: NixOS separates applying a change from repairing a broken system. Each rebuild produces a new immutable generation; activation is atomic; the old generation stays available. You can treat a bad configuration as a rollback, not an outage.
What a generation actually is
In NixOS, the system configuration is described in Nix expressions, usually starting at /etc/nixos/configuration.nix. When you run nixos-rebuild switch, the tool evaluates that configuration, builds a new system closure (the complete set of packages and generated files), and activates it. The result is a new generation, and the bootloader gains an entry for it. The previous generation remains on disk.
Activation is not a sequence of package upgrades that can be interrupted halfway. The new generation is built first, then switched to. If the build fails, the running system is untouched. If the build succeeds but the new generation misbehaves, you can select the old one at boot.
A small worked example: enabling SSH and adding a user
Assume NixOS is installed and you have root or sudo access. Edit /etc/nixos/configuration.nix and add or adjust these declarations:
services.openssh.enable = true;
users.users.alice = {
isNormalUser = true;
extraGroups = [ "wheel" ];
};
Then apply the change from a terminal:
sudo nixos-rebuild switch
What to check after the command returns successfully:
systemctl status sshd— confirms the SSH service is active. The exact unit name can vary; checksystemctl list-units | grep sshif needed.id alice— confirms the user exists and shows group membership. If the user was already logged in, group changes may require a new login session.nixos-rebuild list-generations— lists generations with timestamps. This command exists in recent releases; runnixos-rebuild --helpon your version to confirm.
If the switch fails, read the evaluation error. The running system is still the old generation. Fix the Nix expression and rebuild. If the switch succeeds but SSH does not start, you can roll back without editing files.
Rollback paths and what they do not cover
Two rollback paths are commonly available:
- Boot menu selection. Reboot and choose an older generation from the systemd-boot or GRUB menu. The exact menu layout depends on the bootloader configuration.
- Running-system rollback. From a working shell,
sudo nixos-rebuild switch --rollbackswitches back to the previous generation. Verify the option is supported in your release withnixos-rebuild --help.
The important limitation: generations cover the system closure, not your stateful data. Files under /home, databases in /var/lib, and similar mutable data are not versioned by NixOS. Rolling back the system does not undo a database migration or restore deleted user files. Treat generation rollback as a system-level recovery tool, not a backup strategy.
Another trade-off is disk usage. Every generation keeps its closure, so old generations accumulate. Reclaiming space usually means garbage collection, for example nix-collect-garbage --delete-older-than 30d. That command removes generations older than the given age; check man nix-collect-garbage for your release, and keep at least one known-good generation. The Nix language and module system also have a learning curve, and a syntax error can prevent a rebuild — though the previous generation remains bootable.
How to adopt this without risking the host
Before changing a production machine, build a test VM from the same configuration:
nixos-rebuild build-vm
This produces a script that boots the configuration in a virtual machine. Boot it, verify the service and user changes, then reboot and select the previous generation to confirm rollback works. The exact script name is printed by the build; run it from the directory where you invoked the command.
Keep a short list of known-good generation numbers, and verify after each significant change that the boot menu still offers a fallback. Commands and options can change between NixOS releases, so confirm syntax against the manual and release notes for the version you run. The payoff is a system where a bad configuration change is a reboot away from recovery rather than an afternoon of rescue work.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.