3 07 Troubleshooting
Nimmo edited this page 2026-05-30 22:40:08 +01:00

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:

  1. Error type -- attribute 'nonexistent' missing (the package does not exist)
  2. Location -- /home/nimmo/nixos-config/modules/common/system.nix:10:5 (file, line, column)
  3. 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 btop has the package name btop (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:

  1. Check spelling carefully (somethign vs something)
  2. Verify the module is imported. If you are using a custom module's options, its file must be in the imports list.
  3. 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:

  1. At the boot menu, select a previous generation
  2. Log in and investigate what went wrong
  3. Fix the configuration
  4. 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

  1. At the boot menu, press up/down to find previous generations
  2. Select one that was working
  3. Log in and fix the configuration
  4. Rebuild

Scenario: Cannot log in (graphical session broken)

  1. Press Ctrl+Alt+F2 to switch to a TTY (text console)
  2. Log in as your user
  3. Fix the configuration
  4. 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:

  1. NixOS Discourse (https://discourse.nixos.org/) -- the official forum, generally helpful
  2. NixOS Wiki (https://wiki.nixos.org/) -- community-maintained documentation
  3. NixOS GitHub Issues (https://github.com/NixOS/nixpkgs/issues) -- for bugs in packages or modules
  4. 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.