Table of Contents
- Chapter 7: Troubleshooting
- Reading Nix Error Messages
- Common Problems and Solutions
- Problem: "file not found" or module not visible after creating a new file
- Problem: Package name not found
- Problem: undefined variable 'inputs'
- Problem: Conflicting option definitions
- Problem: Conflicting specialisation overrides
- Problem: Option does not exist
- Problem: Build runs out of disk space
- Problem: Hash mismatch when fetching
- Problem: Service fails after rebuild
- Problem: Boot fails after rebuild
- Problem: Wrong specialisation after nixos-rebuild switch
- Debugging Strategies
- Strategy 1: Isolate the change
- Strategy 2: Build without switching
- Strategy 3: Use test instead of switch
- Strategy 4: Check the Nix REPL
- Strategy 5: Dry-run activation
- Strategy 6: Read the NixOS module source
- Recovery Scenarios
- Scenario: System will not boot
- Scenario: Cannot log in (graphical session broken)
- Scenario: Disk full
- Scenario: Git repository is out of sync
- When to Ask for Help
Chapter 7: Troubleshooting
This chapter covers common errors, how to read Nix error messages, and recovery strategies.
Reading Nix Error Messages
Nix error messages can be verbose and intimidating. Here is how to read them.
Structure of an error
error: attribute 'nonexistent' missing
at /home/nimmo/nixos-config/modules/common/system.nix:10:5:
9| environment.systemPackages = with pkgs; [
10| nonexistent
| ^
11| ];
The key parts:
- Error type --
attribute 'nonexistent' missing(the package does not exist) - Location --
/home/nimmo/nixos-config/modules/common/system.nix:10:5(file, line, column) - Context -- the relevant code with an arrow pointing to the problem
Common error types
attribute 'X' missing -- You referenced something that does not exist. Usually a misspelled package name.
undefined variable 'X' -- You used a name that is not in scope. Often means you forgot to add inputs to a module's function arguments.
infinite recursion encountered -- Two values depend on each other in a cycle. This is less common in configuration files and more common when writing complex modules.
The option 'X' has conflicting definitions -- Two modules set the same non-mergeable option to different values. Use mkForce or mkDefault to resolve priority.
The option 'X' does not exist -- You set an option that no imported module declares. Usually a typo in the option path or a missing import.
Common Problems and Solutions
Problem: "file not found" or module not visible after creating a new file
Cause: Nix flakes only see files tracked by Git.
Solution:
git add path/to/new-file.nix
nix flake check
This is the single most common mistake. Always git add new files before running any Nix command.
Problem: Package name not found
Error:
error: attribute 'wrongname' missing
Cause: The package attribute name does not match what you expected.
Solution: Search for the correct name:
nix search nixpkgs <what-you-are-looking-for>
Or use https://search.nixos.org/packages. The attribute name is not always obvious. For example:
- The program
btophas the package namebtop(straightforward) - LibreOffice for KDE/Qt has the package name
libreoffice-qt6-fresh(not obvious)
Problem: undefined variable 'inputs'
Error:
error: undefined variable 'inputs'
at /home/nimmo/nixos-config/home/nimmo.nix:6:5
Cause: The module uses inputs but does not list it in its function arguments.
Solution: Add inputs to the argument list:
# Before (broken):
{ config, pkgs, ... }:
# After (fixed):
{ config, pkgs, inputs, ... }:
Problem: Conflicting option definitions
Error:
error: The option 'networking.hostName' has conflicting definition values:
- In '/home/nimmo/nixos-config/hosts/electra/default.nix': "electra"
- In '/home/nimmo/nixos-config/hosts/common/default.nix': "something-else"
Cause: Two modules set the same singleton option to different values.
Solution: Remove the duplicate, or use priority functions:
# In the module that should "win":
networking.hostName = lib.mkForce "electra";
# In the module that should be a default:
networking.hostName = lib.mkDefault "default-hostname";
Problem: Conflicting specialisation overrides
Error: Same as conflicting option definitions, but in the context of specialisation blocks.
Cause: Forgetting to use lib.mkForce when overriding a singleton option inside specialisation.<name>.configuration.
# Wrong — will conflict:
specialisation.igpu.configuration = {
boot.kernelPackages = pkgs.linuxPackages_zen; # base already set this
};
# Correct:
specialisation.igpu.configuration = {
boot.kernelPackages = lib.mkForce pkgs.linuxPackages_zen;
};
Problem: Option does not exist
Error:
error: The option 'services.somethign.enable' does not exist.
Cause: Typo in the option path, or the module that declares the option is not imported.
Solution:
- Check spelling carefully (
somethignvssomething) - Verify the module is imported. If you are using a custom module's options, its file must be in the
importslist. - Search for the correct option name: https://search.nixos.org/options
Problem: Build runs out of disk space
Error:
error: writing to file: No space left on device
Solution:
# Remove old generations and unused packages
sudo nix-collect-garbage -d
# Check disk usage
df -h /nix
Your automatic garbage collection should prevent this, but large updates or many generations can fill the disk.
Problem: Hash mismatch when fetching
Error:
error: hash mismatch in fixed-output derivation
specified: sha256-AAAA...
got: sha256-BBBB...
Cause: A fixed-output derivation's contents changed without the hash being updated.
Solution:
# Update the lock file to get fresh hashes
nix flake update
Problem: Service fails after rebuild
Symptom: System rebuilds successfully but a service does not work.
Diagnosis:
# Check the service status
systemctl status <service-name>
# Read the logs
journalctl -u <service-name> -b --no-pager
# Check if the service is enabled
systemctl is-enabled <service-name>
# List failed units
systemctl --failed
Common causes:
- Missing or inaccessible secrets (e.g., restic-backup needs sops-nix secrets from
secrets/secrets.yaml) - Port already in use
- Permissions issues
Problem: Boot fails after rebuild
Solution:
- At the boot menu, select a previous generation
- Log in and investigate what went wrong
- Fix the configuration
- Rebuild with
switch
For electra: if the broken generation was a specialisation, you can also boot the previous generation's base (battery) entry to get a working system.
Problem: Wrong specialisation after nixos-rebuild switch
Symptom: After running nixos-rebuild switch on electra, you are in the base (battery) tier instead of the igpu or dgpu tier you were using.
Cause: nixos-rebuild switch always activates the base tier. The specialisation must be reactivated afterwards.
Solution: Use nixos-rebuild-auto instead of nixos-rebuild switch directly. The nixos-rebuild-auto function reads /etc/nixos-specialisation and re-applies the correct specialisation after switching.
If you used nixos-rebuild switch directly and need to get back to your specialisation:
# Check which specialisation was active
cat /etc/nixos-specialisation # Shows "battery", "igpu", or "dgpu"
# Reactivate the specialisation
sudo /run/current-system/specialisation/igpu/bin/switch-to-configuration switch
Debugging Strategies
Strategy 1: Isolate the change
If a rebuild breaks something, use git diff to see exactly what changed:
git diff HEAD~1
If you changed multiple files, try reverting them one at a time to find which change caused the problem.
Strategy 2: Build without switching
# Build for any host without activating
sudo nixos-rebuild build --flake .#electra
sudo nixos-rebuild build --flake .#lena
This verifies the build succeeds without changing your running system.
Strategy 3: Use test instead of switch
sudo nixos-rebuild test --flake .#electra
This activates the new configuration but does not add it to the boot menu. If it breaks something, just reboot.
Strategy 4: Check the Nix REPL
nix repl
:lf . # Load the current flake
Then you can explore the configuration interactively:
nix-repl> nixosConfigurations.electra.config.networking.hostName
"electra"
nix-repl> nixosConfigurations.lena.config.networking.hostName
"lena"
nix-repl> nixosConfigurations.electra.config.specialisation
{ dgpu = ...; igpu = ...; }
This is extremely useful for debugging. You can inspect any option's evaluated value for any host.
Strategy 5: Dry-run activation
sudo nixos-rebuild dry-activate --flake .#electra
This shows what would change (services restarted, files modified) without actually doing it.
Strategy 6: Read the NixOS module source
When an option does not work as expected, find the module that implements it:
# Find where an option is defined in nixpkgs
nix eval nixpkgs#path --raw
# Then browse: <that-path>/nixos/modules/
Or browse the NixOS module source on GitHub: https://github.com/NixOS/nixpkgs/tree/master/nixos/modules
Recovery Scenarios
Scenario: System will not boot
- At the boot menu, press up/down to find previous generations
- Select one that was working
- Log in and fix the configuration
- Rebuild
Scenario: Cannot log in (graphical session broken)
- Press
Ctrl+Alt+F2to switch to a TTY (text console) - Log in as your user
- Fix the configuration
- Rebuild from the TTY
Scenario: Disk full
# Emergency cleanup: remove ALL old generations
sudo nix-collect-garbage -d
# Check space
df -h /nix
# If still full, find large items
sudo du -sh /nix/store/* | sort -rh | head -20
Scenario: Git repository is out of sync
If the auto-update service pushed changes you do not have locally:
git pull --rebase --autostash
If there are conflicts:
git pull --rebase --autostash
# Resolve conflicts in any conflicting files
git add <resolved-files>
git rebase --continue
When to Ask for Help
After working through these debugging strategies, if you are still stuck:
- NixOS Discourse (https://discourse.nixos.org/) -- the official forum, generally helpful
- NixOS Wiki (https://wiki.nixos.org/) -- community-maintained documentation
- NixOS GitHub Issues (https://github.com/NixOS/nixpkgs/issues) -- for bugs in packages or modules
- The error message itself often contains enough information. Read it carefully, look at the file and line number, and check the code at that location.