Questions about stateVersion

I’m trying to understand stateVersion. There’s the clear recommendation to just not change that - for example, in the nixos manual.

Most users should never change this value after the initial install, for any reason, even if you’ve upgraded your system to a new NixOS release.

However, this just doesn’t make sense to me - things do get old, and the system state can’t magically be an exception. There is the clarification in the manual that

This value does not affect the Nixpkgs version your packages and OS are pulled from, so changing it will not upgrade your system.

However, just a few paragraphs earlier, there is the seemingly contradictory

For example, if NixOS version XX.YY ships with AwesomeDB version N by default, and is then upgraded to version XX.YY+1, which ships AwesomeDB version N+1, the existing databases may no longer be compatible, causing applications to fail, or even leading to data loss.

What happens when AwesomeDB version N reaches end of life? Or the package gets broken, because it’s too old and too difficult to keep fixing?

My point is, the manual states that there’s no problem if stateVersion is old, and it doesn’t relate to system upgrades - and I don’t distrust the manual - but it’s confusing me and I’d like to find a more complete explanation of how that works. But I couldn’t find one anywhere.

What would happen when version N reaches EOL is the module for AwesomeDB will be updated to throw an error for older stateVersions if the package option for AwesomeDB isn’t set.

The idea is that stateVersion controls the default versions of services, so that those defaults can advance for newer configs without automatically upgrading old ones. But old ones can (and should) manually upgrade at some point by setting the package for the service explicitly.

You can see a real example of how this is done for PostgreSQL: https://github.com/NixOS/nixpkgs/blob/2c7f3c0fb7c08a0814627611d9d7d45ab6d75335/nixos/modules/services/databases/postgresql.nix#L486-L498

The stateVersions that defaulted to versions 13-15 set the package appropriately, but older ones that used 11, 9.6, and 9.5 will throw an error. That doesn’t mean you can’t use the module with a stateVersion that old, just that you have to set services.postgresql.package to a version that is still supported, and if you were running an older one before, you’ll need to manually handle the upgrade.

2 Likes