Cannot Enable Unfree Nix Flake Home Manager

Hello! I am new to NixOS. Spent all last night converting my Arch Linux Sway config over to NixOS and it went swimmingly. Until I tried to install Steam. Here is my flake.nix and home.nix:

{
  description = "NixOS system flake.";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";

    nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-23.11";

    home-manager = {
        url = "github:nix-community/home-manager";
        inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, nixpkgs-stable, home-manager, ... } @ inputs:
  let
    inherit (self) outputs;
    system = "x86_64-linux";
    userName = "nate";
    hostName = "winmax";
    pkgs = nixpkgs.legacyPackages.${system};
    stablePkgs = import nixpkgs-stable {
        legacyPackages = system;
        ####
        config.allowUnfree = true;  
        ####
        #### Tried it here for stablePkgs and pkgs and it doesnt work
    };
  in
  {
    nixosConfigurations = {
      nixSway = nixpkgs.lib.nixosSystem {
        # Pass args to sway_configuration
        specialArgs = {
            inherit inputs;
            inherit userName;
            inherit hostName;
        };
        modules = [
          ./nixos/sway_configuration.nix
          # Setup home manager
          home-manager.nixosModules.home-manager {
              home-manager.useGlobalPkgs = true;
              home-manager.useUserPackages = true;
              home-manager.users.${userName} = import ./modules/home-manager/home.nix;
              # Pass args to home.nix
              home-manager.extraSpecialArgs = {
                  inherit inputs outputs userName hostName;
              };
          }
        ];
      };
    };
  };
}
{ inputs, outputs, lib, config, pkgs, userName, hostName, ... }:
{
  # Home Manager needs a bit of information about you and the paths it should
  # manage.
  #

  nixpkgs.config.allowUnfree = true;
  #### Doesnt work here either...
  # inputs.nixpkgs-stable.config.allowUnfree = true;
  ####  

  home.username = userName;
  home.homeDirectory = "/home/${userName}";
  home.packages = with pkgs; [
    steam
  # ... The rest of the config

The error:

 error: Package ‘steam’ in /nix/store/4fgs7yzsy2dqnjw8j42qlp9i1vgarzy0-source/pkgs/games/steam/steam.nix:43 has an unfree license (‘unfreeRedistributable’), refusing to evaluate.

Any help on this? Sorry Im sure so many people come here with noob questions, but I have searched for solutions and haven’t been able to find any.

As an aside, Im still trying to understand the inputs/outputs. Im familiar with the let in syntax from ocaml, but is there a way I can get userName from outputs that Im passing into home.nix? outputs.userName doesnt seem to work as I would expect.

If you have any insights or tips please let me know. Im very new to Nix, my config is a frankenstein of other people’s configs as I was working through learning. Also, is there an easy way to inspect what is in an attribute? Like some sort of repl?

Git link for full config

Quoting the home-manager docs:

By default, Home Manager uses a private pkgs instance that is configured via the home-manager.users..nixpkgs options. To instead use the global pkgs that is configured via the system level nixpkgs options, set

home-manager.useGlobalPkgs = true;

This saves an extra Nixpkgs evaluation, adds consistency, and removes the dependency on NIX_PATH, which is otherwise used for importing Nixpkgs.

This means that with your current configuration, the home-manager packages will come from the same nixpkgs as the one whose lib.nixosSystem you’re calling. I.e., if you want to allow unfree packages, you need to set the NixOS modules’ nixpkgs.config.allowUnfree, not the one from inside your home-manager config, and definitely not the one used in a stable nixpkgs that isn’t even used in your configuration afaict.

You’re not showing what’s inside of ./nixos/sway_configuration.nix, but you could place it there, or more reasonably in a ./nixos/default.nix.

Not really, unless you invent your own non-standard flake output attribute.

In theory you could get it from the config arg of the NixOS module, but home-manager.users is an attrset so that’d still be quite awkward.

The way you’re doing it now seems ideal to me.

Consider using allowUnfreePredicate instead of allowUnfree so you get a warning when you use non-free packages. Besides my ideological concerns - that may or may not seem irrelevant in the face of the cold, hard realism of the desktop software ecosystem - plenty of proprietary software is difficult to package, since NixOS is never a first party support target, which often results in poor user experience and long package update cycles. It’s best to at least be aware of which packages you’re using that will struggle.

When using flakes, try to avoid the import <nixpkgs> way of importing nixpkgs if you can. Every invocation of this sort will evaluate a new nixpkgs, whereas <nixpkgs>.legacyPackages.${sytem} can instead use the caching features.

This is mostly not a big deal for system config flakes like this one, but I’d say get into the habit of avoiding this early. If you need unfree packages from a specific nixpkgs flake input, you can use nixpkgs-unfree until there’s a better solution.

Besides this, I’d advise placing:

Somewhere in your config, rather than inside your flake.nix. Sure, this is ultimately a style choice, but keeping flake.nix as simple as reasonably possible results in better separation of concerns IME. flake.nix can get very complex if you end up importing a variety of things, and maybe adding tests and other things in the future, best not to muddy the waters even more.

For similar reasons, I’d also recommend creating a top-level ./nixos/default.nix, and using its imports instead of listing all your modules in the nixosSystem’s modules arg.

nix repl exists, and you can load your flake with the :lf macro, at which point you can pretty much inspect anything.

1 Like

Thank you so much for the detailed response. I really appreciate it. Do you have a buy me a coffee or something, genuinely I was so frustrated lol and was so relieved to have someone respond.

I didnt include my sway_configuration.nix, but like you suggested, I added:

{ config, lib, pkgs, userName, hostName, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
      ../modules/user/main_user.nix
    ];

  # Enable flakes feature
  nix.settings.experimental-features = [
    "nix-command" "flakes"
  ];

### This line here
  nixpkgs.config.allowUnfree = true;
### 

<...the rest...>

And that allowed me to install steam in my home.nix. It makes sense that I have to enable that option in the sway_configuration.nix after pinning the home-manager to use the global pkgs.

I share the sentiment, and appreciate the option for the warning, definitely will use. Ideally I like to think I am in the freedom absolutist camp when it comes to software, but gaming with friends is I guess the exception I make.

Seriously, thanks so much for the detailed response. I got the minimal change working, but I agree that some organizing is needed in my config to clean it up and make it more modular, and I think the default.nix config sounds like a good way to go.

Hah, no, but it’s probably not a terrible idea to set up the github sponsors thing in case someone else feels generous some day in the future.

That said - as much as I could use it - not sure how I’d feel about being incentivized to answer faster than others. Maybe buy a t-shirt or something from the foundation instead, keeping the lights on around here is probably more helpful than sustaining my sabbatical.

Yeah, I know the feeling. And as far as proprietary overlords go, valve have been pretty good citizens. Just wish they were a bit less cagey about their client’s source code.