To define or to not define nixpkgs.hostPlatform

I’ve found myself in a catch-22 situation: nixpkgs.lib.nixosSystem wants me to define nixpkgs.hostPlatform in one of the system’s modules, and nixpkgs.legacyPackages.<platform>.testers.runNixOSTest wants me to not define it.

Concretely, consider this flake:

flake.nix
{
  inputs = {
    nixpkgs.url = "https://channels.nixos.org/nixos-25.11/nixexprs.tar.xz";
  };
  outputs = {
    self, nixpkgs, ...
  }: let
    hostPlatform = "x86_64-linux";
    baseModules = [
      {
        nix.registry.nixpkgs.flake = nixpkgs;
        # if the following setting is present, nixosConfigurations.demo
        # can be built but checks.demo can't. if it is absent, checks.demo
        # can be built but nixosConfigurations.demo can't.
        nixpkgs.hostPlatform = hostPlatform;
      }
    ];
    demoModules = [
      {
        system.stateVersion = "25.11";
        boot.loader.grub.devices = ["/dev/vda"];
        fileSystems."/" = {
          device = "/dev/vda1";
        };
      }
    ];
    prodSystem = name: modules:
      nixpkgs.lib.nixosSystem {
        modules = baseModules ++ modules;
        system = null;
      };
    testSystem = name: modules:
      nixpkgs.legacyPackages."${hostPlatform}".testers.runNixOSTest {
        name = "test that ${name} boots";
        nodes.machine = { ... }: {
          imports = baseModules ++ modules;
        };
        testScript = ''
          machine.start()
          machine.wait_for_unit("default.target")
          machine.succeed("uname -a")
        '';
      };

  in {
    nixosConfigurations = {
      demo = prodSystem "demo" demoModules;
    };
    checks = {
      demo = testSystem "demo" demoModules;
    };
  };
}

With the nixpkgs.hostPlatform line present within baseModules, nix build '.#nixosConfigurations.demo.config.system.build.toplevel' completes without error, but nix build '.#checks.demo' errors out like this:

error: The option `nodes.machine.nixpkgs.hostPlatform' is read-only, but it's
set multiple times. Definition values:
- In `/nix/store/nkrpxas3mvs0nlaxzqdjgnj849q6j1am-source/nixos/modules/misc/nixpkgs/read-only.nix':
    {
      aesSupport = false;
      androidNdkVersion = null;
      androidSdkVersion = null;
      avx2Support = false;
    ...
- In `the argument that was passed to pkgs.runNixOSTest': "x86_64-linux"

note: trace involved the following derivations:
derivation 'vm-test-run-test-that-demo-boots'
derivation 'nixos-test-driver-test-that-demo-boots'

If the nixpkgs.hostPlatform line is removed, it’s just the opposite: nix build '.#checks.demo' completes successfully[1] but nix build '.#nixosConfigurations.demo.config.system.build.toplevel' bombs out with

error: Neither nixpkgs.hostPlatform nor the legacy option nixpkgs.system has
been set. You can set nixpkgs.hostPlatform in hardware-configuration.nix by
re-running a recent version of nixos-generate-config.
The option nixpkgs.system is still fully supported for NixOS 22.05
interoperability, but will be deprecated in the future, so we recommend to set
nixpkgs.hostPlatform.

What do I have to do to make both build targets succeed from the same flake? My larger goal is to be able to run test VMs built from almost exactly the same modules as my real systems; a solution that avoids changing either baseModules or demoModules is strongly preferred.


  1. N.B. I’m not sure it actually ran the test; if anyone knows how to see more detail than just “the nix build command sits for a while at ‘building nix-test-run-test’ and then exits without error”, I’d love to hear about it. ↩︎

Evidently you can set something like node.pkgsReadOnly = false; or set node.pkgs = null; when calling runTest as mentioned here (actually those are the default values, so just set neither):

As you can see, runNixOSTest sets node.pkgs directly, so you could call runTest similarly to runNixOSTest without setting that option.