Unable to install unfree packages with home manager flake even with config.allowUnfree = true

Hello,

I recently moved to the flake based home manager. I didn’t have this issue on the old non-flake home manager.

I am aware that this issue has already been mentioned several times in the past here and in other places. However, I couldn’t find any solution or mention of this issue for non-NixOS distros.

System Specs
System:
  Kernel: 6.12.31-1-lts arch: x86_64 bits: 64 compiler: gcc v: 15.1.1
    clocksource: tsc avail: hpet,acpi_pm
    parameters: BOOT_IMAGE=/@/boot/vmlinuz-linux-lts
    root=UUID=50a0e52f-4c78-4ef8-9f28-035e9a972853 rw rootflags=subvol=@
    nowatchdog nvme_load=YES rd.luks.uuid=256a30de-ba5f-4b0f-8f79-0db4cc84e305
    loglevel=3 nvidia-drm.modeset=1 nvidia-drm.fbdev=1
  Desktop: KDE Plasma v: 6.3.5 tk: Qt v: N/A info: frameworks v: 6.14.0
    wm: kwin_x11 vt: 2 dm: SDDM Distro: EndeavourOS base: Arch Linux
Machine:
  Type: Laptop System: Apple product: MacBookPro10,1 v: 1.0
    serial: <superuser required> Chassis: type: 10 v: Mac-C3EC7CD22292981F
    serial: <superuser required>
  Mobo: Apple model: Mac-C3EC7CD22292981F v: MacBookPro10,1
    serial: <superuser required> uuid: <superuser required> UEFI: Apple
    v: 429.0.0.0.0 date: 03/18/2022
CPU:
  Info: model: Intel Core i7-3615QM bits: 64 type: MT MCP arch: Ivy Bridge
    gen: core 3 level: v2 built: 2012-15 process: Intel 22nm family: 6
    model-id: 0x3A (58) stepping: 9 microcode: 0x21
  Topology: cpus: 1x dies: 1 clusters: 4 cores: 4 threads: 8 tpc: 2
    smt: enabled cache: L1: 256 KiB desc: d-4x32 KiB; i-4x32 KiB L2: 1024 KiB
    desc: 4x256 KiB L3: 6 MiB desc: 1x6 MiB
  Speed (MHz): avg: 1209 min/max: 1200/3300 scaling: driver: intel_cpufreq
    governor: schedutil cores: 1: 1209 2: 1209 3: 1209 4: 1209 5: 1209 6: 1209
    7: 1209 8: 1209 bogomips: 36729
  Flags: avx ht lm nx pae sse sse2 sse3 sse4_1 sse4_2 ssse3 vmx
  Vulnerabilities:
  Type: gather_data_sampling status: Not affected
  Type: indirect_target_selection status: Not affected
  Type: itlb_multihit status: KVM: Split huge pages
  Type: l1tf mitigation: PTE Inversion; VMX: conditional cache flushes, SMT
    vulnerable
  Type: mds mitigation: Clear CPU buffers; SMT vulnerable
  Type: meltdown mitigation: PTI
  Type: mmio_stale_data status: Unknown: No mitigations
  Type: reg_file_data_sampling status: Not affected
  Type: retbleed status: Not affected
  Type: spec_rstack_overflow status: Not affected
  Type: spec_store_bypass mitigation: Speculative Store Bypass disabled via
    prctl
  Type: spectre_v1 mitigation: usercopy/swapgs barriers and __user pointer
    sanitization
  Type: spectre_v2 mitigation: Retpolines; IBPB: conditional; IBRS_FW;
    STIBP: conditional; RSB filling; PBRSB-eIBRS: Not affected; BHI: Not
    affected
  Type: srbds status: Vulnerable: No microcode
  Type: tsx_async_abort status: Not affected
  Packages: 1263 pm: nix-default pkgs: 64 pm: nix-sys pkgs: 0 pm: nix-usr
    pkgs: 100 libs: 16 pm: pacman pkgs: 1085 libs: 282 tools: yay pm: flatpak
    pkgs: 14 Compilers: gcc: 15.1.1 Shell: Bash v: 5.2.37 running-in: konsole
    inxi: 3.3.38
My `flake.nix` file
{
  description = "Home Manager configuration of chirag";

  inputs = {
    # Specify the source of Home Manager and Nixpkgs.
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    home-manager = {
      url = "github:nix-community/home-manager/master";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    nixGL = {
      url = "github:nix-community/nixGL";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    tldr = {
      type = "github";
      owner = "tldr-pages";
      repo = "tldr";
      flake = false;
    };
  };

  outputs =
    { nixpkgs, home-manager, ... }@inputs:
    let
      system = "x86_64-linux";
      # pkgs = nixpkgs.legacyPackages.${system};
      pkgs = import inputs.nixpkgs { inherit system; config.allowUnfree = true; };
    in
    {
      homeConfigurations."chirag" = home-manager.lib.homeManagerConfiguration {
        inherit pkgs;

        # Specify your home configuration modules here, for example,
        # the path to your home.nix.
        modules = [ ./home.nix ];

        # Optionally use extraSpecialArgs
        # to pass through arguments to home.nix
        extraSpecialArgs = {
          nixgl = inputs.nixGL;
          tldr = inputs.tldr;
        };
      };
    };
}

Brief version of my `home.nix` file
{ config, lib, pkgs, nixgl, tldr, ... }:
{
  home.username = "myuser";
  home.homeDirectory = "/home/myuser";

  targets.genericLinux.enable = true;

  # Get NixGL
  nixGL.packages = nixgl.packages;
  nixGL.defaultWrapper = "nvidia";
  nixGL.offloadWrapper = "nvidiaPrime";

  home.stateVersion = "25.05";

  home.packages = with pkgs; [
      ...
  ];

  home.file = {
      ...
  };
  programs.ghostty = import ./ghostty.nix { inherit config pkgs lib; };
}
My `ghostty.nix` file
{config, lib, pkgs, ...}:
{
    enable = true;
    package = config.lib.nixGL.wrap pkgs.ghostty;
    enableBashIntegration = true;
    settings = {
        ...
    };
}

The command I’m using to build the configuration is:

home-manager switch --impure

Solutions that work


Adding the following to ~/.config/nixpkgs/config.nix works without any issues.

{
    allowUnfree = true;
}

Alternatively, running the following command (without having to set allowUnfree in config.nix) also seems to work:

NIXPKGS_ALLOW_UNFREE=1 home-manager switch --impure

Related issue on Discourse:


I came across a related issue here in discourse. I created a flake.nix that produces a simple nix shell environment just as shown in the discourse post, and in the output section of flake.nix, I set pkgs = import nixpkgs {inherit system; config.allowUnfree = true;}; and I was able to run nix develop and install mongodb without any issues. But for some reason, I’m not able to do the same with home-manager. This solutions seems to be working for a lot of others but not in my case.

Questions:


  1. What could be the reason that even after setting pkgs = import inputs.nixpkgs { inherit system; config.allowUnfree = true; }; in my flake.nix, Nix is refusing to evaluate?
  2. Am I missing something? How should I write my flake so as not to always depend on ~/.config/nixpkgs/config.nix?
  3. Is there a bug in home-manager?

Thank you very much for your help.

Do not pass a preconfigured nixpkgs instance to HM.

Use pkgs = nixpkgs.legacyPackages.x86_64-linux instead and then use HMs nixpkgs options to configure the it.

Also you should leverage the module system better for your ghostty configuration.

Last but not least, the unfree error might happen for nixgl. Which uses its own instance of nixpkgs. I do not use nixgl the way you do, and don’t know how to solve that then.

2 Likes

Thank you very much @NobbZ for taking the time go through this and reply so quickly!

I am still new and learning Nix. Moreover, I’m using Nix on a non-NixOS distro which I’m assuming complicates things for me.

I did try setting the nixpkgs option within HM at first but this did not work in my current flake based HM. In fact, I used to set it in the old non-flake version of HM and that used to work.

So I have a couple of questions now:

  1. Would setting the allowUnfree or allowUnfreePredicate in ~/.config/nixpkgs/conf.nix, be a best practice way of doing things? This seems to be like an easy way out.
  2. What does it mean when Eelco Dolstra says ‘evaluation isn’t as hermetic as it could be’ in his flakes intro blog post?
  3. Could you share some tips on how I can leverage the module system better? Maybe there is documentation I could consult? I have already gone through the official HM document, but a reference to a specific topic/code snippet would be great.

Thanks again.

No, especially not with flakes. You should stop using the --impure flag, and the entire reason that file does anything is because of that flag.

You can read files from e.g. ~/.config/nixpkgs/conf.nix. This doesn’t seem so bad at first, just copy that nix config everywhere you evaluate your project, until you realize that you can read stuff from anywhere.

Imagine someone writes a configuration that reads content from e.g. the shadow file. Good luck reproducing that anywhere.

The entire idea behind nix as a project is to make it as impossible as possible to build projects that do things that are hard to reproduce on other systems. By evaluating stuff from third files, you’re creating dependencies that won’t be met elsewhere. conf.nix is especially bad, actually, your config will fail to evaluate (even just for inspection purposes) for any user who doesn’t want to blanket enable all unfree packages.

What eelco is saying is ,this could be avoided - by introducing flakes, which only have --impure as an escape hatch for newbies who don’t know what they’re doing or people who have existing code that is infeasible to untangle.

Instead of:

Do:

imports = [
  ./ghostty.nix
]

The module system takes all files, evaluates them (by executing the functions they define, giving them the arguments in _module.args if they are functions, or just evaluating the attraets if they are attrsets), then merges all settings together.

What you’re doing atm works, but you’re bypassing the module system, which means things won’t be merged and you can’t make use of the module system’s various features properly. The imports attr is part of the stuff the module system inspects, import is a nix builtin which just evaluates a single file and puts its result in the location it is.

This is technically more about the NixOS module system, but home-manager’s is practically equivalent (I think it might even reuse the module system code these days): Module system — nix.dev documentation

2 Likes

Thank you very much @TLATER for taking the time to provide the detailed answer! I understand things better now.

Thanks again to you guys @NobbZ @TLATER, I modified my home.nix to take advantage of the module system. It is an elegant solution and my home.nix is looking more tidy.

I was also able to narrow down the issue to nixGL. There is no bug/issue with home-manager. I am able to install packages with unfree licenses by setting setting the nixpkgs.config attribute within home-manager based on suggestion from @NobbZ. This was the same solution I used in the past in my non-flake home-manager.

Now the issue seems to be with using nixGL as a flake. I tried the nixGL option of HM instead and I’m able to run home-manager switch without the --impure flag and I’m able to evaluate home.nix but I’m unable to start ghostty due to the Failed to create EGL message. I’m looking into how I can get the nixGL HM option to install legacy NVIDIA driver support for my machine (macbookpro10,1). The documentation says I need to use the backport/noGLVND but I’m not sure how to do things the flake way.

It appears to me that if I use any variant of the NVIDIA wrapper via nixGL, I must use the --impure option because the nixGL module is performing auto-detection of driver version through an impure operation of reading the NVIDIA driver version from /proc/driver/nvidia/version.

In github:nix-community/nixGL/nixGL.nix I see the following:

      # HACK: Get the version from /proc. It turns out that /proc is mounted
      # inside of the build sandbox and varies from machine to machine.
      #
      # builtins.readFile is not able to read /proc files. See
      # https://github.com/NixOS/nix/issues/3539.
        runCommand "impure-nvidia-version-file" {
          # To avoid sharing the build result over time or between machine,
          # Add an impure parameter to force the rebuild on each access.
          time = builtins.currentTime;
          preferLocalBuild = true;
          allowSubstitutes = false;
        } "cp /proc/driver/nvidia/version $out 2> /dev/null || touch $out";

I have a question:

  1. Is it even possible for non-NixOS systems to have a pure implementation of nixGL? I think this is a complex problem.

NixGL sucks and anyway, I thought it wasn’t needed anymore since 25.05? Though I haven’t tested it myself since the release.

It still seems to be required. At least for neovide and ghostty, which were the 2 applications I tested right now on my Ubuntu system. As those are the 2 for which I initially used it.

Maybe the situation imroved for some applications, but definitely not for all of them.

I circumvent the impure nvidia problem by just using the iGPU for neovide, that one is “good enough”.

And by today neovide is the only thing I am wrapping.

2 Likes

nix-system-graphics[1] could be considered. It does require some additional configuration, like using system-manager[2], but it has some benefits over nixGL, e.g. no --impure, no nixGL <somecommand>, has an open source license[3].


  1. GitHub - soupglasses/nix-system-graphics: Run graphics accelerated programs built with Nix on any Linux distribution. ↩︎

  2. GitHub - numtide/system-manager: Manage system config using nix on any distro ↩︎

  3. GitHub - soupglasses/nix-system-graphics: Run graphics accelerated programs built with Nix on any Linux distribution. ↩︎

1 Like

Thank you for confirming. I guess as open-source GPU drivers become better, we might not have to worry about the impurities in Nix expressions.

Thank you for the suggestion, It looks like a great project. It might just be what I’m looking for.

1 Like