Skip to main content
Validation is a critical step before any deployment. The homelab follows the philosophy: “nix flake check is the law.” Always validate before deploying.

Why Validation Matters

Validation prevents:
  • Syntax errors in Nix expressions
  • Type mismatches and incorrect options
  • Missing dependencies or broken imports
  • Failed deployments that could leave systems in broken states
  • Time wasted on deployments that will fail
Never skip validation before deploying to production systems. A failed deployment can leave your system in an inconsistent state.

Primary Validation Command

The main validation command checks all configurations in your flake:
nix flake check
This validates:
  • All NixOS system configurations (nixosConfigurations)
  • All Home Manager configurations (homeConfigurations)
  • All Nix-on-Droid configurations (nixOnDroidConfigurations)
  • Development shells and packages
  • Flake structure and metadata

Validation Workflow

1

Navigate to repository

cd /path/to/homelab
2

Run flake check

nix flake check
This command evaluates all configurations without building or deploying them.
3

Review output

Look for any errors or warnings in the output. The check will fail if any configuration has issues.
4

Fix issues

If errors are found, correct them and run the check again until it passes.
5

Proceed with deployment

Only after a successful check should you deploy.

Validation Options

# Validate all configurations
nix flake check

What Gets Validated

The flake includes comprehensive evaluation checks:
checks = let
  # Evaluation checks for all NixOS systems
  evalSystems = lib.mapAttrs' (name: conf: {
    name = "system-eval-${name}";
    value = conf.config.system.build.toplevel;
  }) self.nixosConfigurations;

  # Evaluation checks for all homes
  evalHomes = lib.mapAttrs' (name: conf: {
    name = "home-eval-${name}";
    value = conf.activationPackage;
  }) self.homeConfigurations;

  # Evaluation checks for all droids
  evalDroids = lib.mapAttrs' (name: conf: {
    name = "droid-eval-${name}";
    value = conf.activationPackage;
  }) self.nixOnDroidConfigurations;
in
  evalSystems // evalHomes // evalDroids;

Security Validation

The homelab includes a security audit tool:
nix run .#check
This runs:
  1. vulnix - Scans for known security vulnerabilities in dependencies
  2. nix flake check - Standard configuration validation
Output shows any packages with known CVEs:
Package: package-name-1.2.3
CVE: CVE-2024-XXXXX
Severity: High
Status: Unpatched

Whitelist Management

Accepted vulnerabilities are documented in vulnix-whitelist.toml:
# vulnix-whitelist.toml
["CVE-2024-12345"]
reason = "False positive - not applicable to our use case"
until = "2024-12-31"

Targeted Validation

Validate Specific Configuration

Check a single system without validating everything:
# NixOS system
nix build .#nixosConfigurations.<hostname>.config.system.build.toplevel

# Home Manager configuration
nix build .#homeConfigurations.<username>.activationPackage

# Nix-on-Droid configuration
nix build .#nixOnDroidConfigurations.<device>.activationPackage

Validate Flake Metadata

Check flake structure and inputs:
nix flake metadata

Validate Flake Schema

Ensure flake outputs are correctly structured:
nix flake show

Pre-commit Validation

The repository includes automatic validation via git hooks:
# pre-commit.nix
pre-commit = {
  check.enable = true;
  settings.hooks = {
    # Formatting checks
    treefmt.enable = true;
    
    # Nix-specific checks
    nixpkgs-fmt.enable = true;
    statix.enable = true;
    deadnix.enable = true;
  };
};
These run automatically before each commit when using the dev shell.

Continuous Integration

GitHub Actions automatically validate on push:
# .github/workflows/check.yml (auto-generated)
name: Flake Check
on: [push, pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: DeterminateSystems/nix-installer-action@main
      - run: nix flake check -L

Common Validation Errors

Syntax Errors

Error: error: syntax error, unexpected '}' Solution: Check for missing semicolons, brackets, or quotes in Nix files.

Missing Options

Error: error: The option 'services.xyz' does not exist Solution:
  • Check option name spelling
  • Verify the module providing the option is imported
  • Check NixOS option search: https://search.nixos.org

Type Mismatches

Error: error: value is a list while a set was expected Solution: Review the option’s expected type and correct your configuration.

Import Errors

Error: error: file 'path/to/module.nix' was not found Solution:
  • Verify file path is correct
  • Ensure file exists in repository
  • Check for typos in import statements

Infinite Recursion

Error: error: infinite recursion encountered Solution:
  • Check for circular imports
  • Review lib.mkIf, lib.mkDefault, and lib.mkOverride usage
  • Look for self-referential definitions

Validation Best Practices

1

Validate frequently

Run nix flake check after any configuration change, not just before deployment.
2

Use the dev shell

The dev shell includes pre-commit hooks that catch issues early:
direnv allow  # or nix develop
3

Test incrementally

Make small changes and validate each one. Don’t accumulate multiple changes before validation.
4

Run security checks

Periodically run vulnerability scans:
nix run .#check
5

Review CI results

Check GitHub Actions output for validation failures on all systems.

Validation vs. Testing

Validation (Evaluation)

Validation ensures configuration is syntactically correct and evaluates properly:
nix flake check  # Evaluates but doesn't build

Testing (Build + Test)

Testing actually builds and can test the configuration:
# Build without activating
nixos-rebuild build --flake .#<hostname>

# Test temporarily (reverts on reboot)
nixos-rebuild test --flake .#<hostname>

Updating Before Validation

When updating inputs, validate afterward:
# Update all inputs
nix flake update

# Validate updated configuration
nix flake check

# Update specific input
nix flake lock --update-input nixpkgs-weekly
nix flake check

Debugging Validation Failures

Get Detailed Error Information

# Show full build logs
nix flake check -L

# Show evaluation trace
nix flake check --show-trace

# Debug specific configuration
nix eval .#nixosConfigurations.<hostname>.config.system.build.toplevel --show-trace

Isolate the Problem

  1. Comment out recent changes
  2. Run validation after each uncomment
  3. Identify which change causes the failure
  4. Fix that specific change

Check Individual Outputs

# List all flake outputs
nix flake show

# Evaluate specific output
nix eval .#nixosConfigurations.<hostname>.config --apply 'x: x.networking.hostName'

Validation in Development Workflow

Next Steps

After successful validation:
Remember: “nix flake check is the law.” Never deploy without validation.

Build docs developers (and LLMs) love