The already known GPG issuse

Hey guys,

Does Nixos contains after 5 years a solution to get gpg working?
Since I found this post: Can't get gnupg to work: no pinentry

The initial post is from 2021 and I have the same Issue in 2026?

Is there somewhere a solution to get it runnig, or do I have to search for an other distrio?
I completly reinstall my whole machine with the newest version, updated all. Do the settings like explaind, used all possible combinations but NOTHING works.

1 Like

How does your config look like, and did you reboot?

always rebooting after making any changes.

{ pkgs, lib, config, ... }: {
  options = {
    gnupg.enable = lib.mkEnableOption "enable gnupg";
  };

  config = lib.mkIf config.gnupg.enable {
    environment.systemPackages = with pkgs; [
      gnupg
      pinentry-curses
    ];

    programs.gnupg.agent = {
      enable = true;
      enableSSHSupport = true;
      pinentryPackage = pkgs.pinentry-curses;
    };
    
    services.dbus.packages = [pkgs.gcr];
    services.pcscd.enable = true;
  };
}

remove pinentry-curses from the environment.systemPackages.

removing the pinentry packages from systemPackages does not change anything

Then I am out of ideas, for me it worked back then. Though I had to reboot after any change, as there is some nasty caching of failure states in GnuPG.

Pinentry provides a console and (optional) GTK and Qt GUIs allowing users to enter a passphrase when gpg or gpg2 is run and needs it.


It is password promoter with gui password promoter when it is needed. Not generate GPG keys that is all another thing if I am correct

Also rebooting do you run nixos switch to actually update the system settings after changing settings no need to reboot

If you read the post you linked, you’ll notice that the OP there also said in 2021:

Please don’t make this into some kind of witch-hunt about bugs not being addressed.

Please do provide details on what you tried (in sufficient detail that a stranger could reproduce it on a VM, ideally) and what happens when you do try. Hoping you do get this solved, as computer problems can be frustrating for sure.

config:

{ pkgs, lib, config, ... }: {
  options = {
    gnupg.enable = lib.mkEnableOption "enable gnupg";
  };

  config = lib.mkIf config.gnupg.enable {
    environment.systemPackages = with pkgs; [
      gnupg
      pinentry-curses
    ];

    programs.gnupg.agent = {
      enable = true;
      enableSSHSupport = true;
      pinentryPackage = pkgs.pinentry-curses;
    };
    
    services.dbus.packages = [pkgs.gcr];
    services.pcscd.enable = true;
  };
}

I use be command:

sudo nixos-rebuild switch --flake .#nixos-workstation

I the console:

gpg --edit-key <key-id>
gpg> adduid

=> no prompt to enter the password appears.

What I have tried:

  • I used all pinentry possibilities.
  • services.pcscd.enable = true;
  • $ cat ~/.gnupg/gpg-agent.conf
    pinentry-program /run/current-system/sw/bin/pinentry
  • users.users..packages = [pkgs.gnupg]
  • users.users..packages = [pkgs.pinentry-xxx]
  • users.users..packages = [pgs.gnupg pkgs.pinentry-xxx]
  • services.dbus.packages = [pkgs.gcr];
â—Ź gpg-agent.service - GnuPG cryptographic agent and passphrase cache
     Loaded: loaded (/etc/systemd/user/gpg-agent.service; static)
     Active: active (running) since Thu 2026-04-16 17:18:53 CEST; 3min 35s ago
 Invocation: 38a7f7f5587a464a8bb12e8f6b4c9406
TriggeredBy: â—Ź gpg-agent.socket
             â—Ź gpg-agent-ssh.socket
       Docs: man:gpg-agent(1)
   Main PID: 14395 (gpg-agent)
      Tasks: 1 (limit: 28718)
     Memory: 1.3M (peak: 2.2M)
        CPU: 18ms
     CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/gpg-agent.service
             └─14395 /nix/store/k4d44dcjlqp3xr849x985myp0slfhp9n-gnupg-2.4.9/bin/gpg-agent --supervised

Apr 16 17:18:53 nixos-workstation systemd[1866]: Started GnuPG cryptographic agent and passphrase cache.
Apr 16 17:18:53 nixos-workstation gpg-agent[14395]: gpg-agent (GnuPG) 2.4.9 starting in supervised mode.
Apr 16 17:18:53 nixos-workstation gpg-agent[14395]: using fd 3 for std socket (/run/user/1000/gnupg/S.gpg-agent)
Apr 16 17:18:53 nixos-workstation gpg-agent[14395]: using fd 4 for ssh socket (/run/user/1000/gnupg/S.gpg-agent.ssh)
Apr 16 17:18:53 nixos-workstation gpg-agent[14395]: listening on: std=3 extra=-1 browser=-1 ssh=4
  1. This is incredibly basic, but do you actually have gnupg.enable = true; somewhere in your configuration? The Nix configuration fragment you showed won’t do anything unless you also add that setting, outside the config = lib.mkIf config.gnupg.enable block.
  2. What do ls -l /run/current-system/sw/bin/pinentry and ls -l $(dirname $(readlink /run/current-system/sw/bin/pinentry)) print?
  3. Assuming the commands in step 2 indicate that /run/current-system/sw/bin/pinentry does exist and isn’t a broken symbolic link, what happens if you run it by hand from the shell?
1 Like

That option doesn’t exist. I checked before suggesting to make sure.

@NobbZ The config fragment shown by OP defines that option, and everything else it does is conditional on the option being set true.

1 Like

Oh, I was reading your suggestion as programs.gnupg.enable.

Hmmm…. I had a chance to look at my config and all I’m seeing is the following:

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

{
  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  programs.gnupg.agent = {
    enable = true;
    enableSSHSupport = true;
  };
}

and

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

{
  environment.systemPackages = with pkgs; [
    gnupg
    pinentry-curses
  ];
}

This works fine with gpg for me. What happens if you run pinentry-curses and then type getpin at the resulting prompt?

(as for the gcr and pcscd stuff, I’m not sure)

  1. I check every file, there is just one declaration and thats inside the shown setting.
ls -l /run/current-system/sw/bin/pinentry
 ls -l /run/current-system/sw/bin/pinentry
lrwxrwxrwx 1 root root 78  1. Jan 1970  /run/current-system/sw/bin/pinentry -> /nix/store/i0q75c4vkrwlv5i8sd8dzv2sk098vqg2-pinentry-curses-1.3.2/bin/pinentry
ls -l $(dirname $(readlink /run/current-system/sw/bin/pinentry))
insgesamt 192
lrwxrwxrwx 1 root root     15  1. Jan 1970  pinentry -> pinentry-curses
-r-xr-xr-x 1 root root 103016  1. Jan 1970  pinentry-curses
-r-xr-xr-x 1 root root  83864  1. Jan 1970  pinentry-tty

The gcr and pcscd stuff was set as a solution from an other guy with the same issue.

calling pinentry-curses then fill in getpin opens a pin entry dialog in the shell.

Check ps -a | grep gpg for any extra gpg-related services. Shell init tutorials often include snippets for launching the gpg agent, which would interfere with your NixOS settings.

I’d suspect that you’re not inheriting the login shell session correctly, and/or missing the systemd variable import. Share your full configuration.nix, as well as any shell and xinit or wayland compositor config files you use that aren’t tracked by it.

Sharing the output of env in the shell you’re using for gpg would help a ton, too.

It seems this leeds to the right path… the output of ps -a | grep gpg is empty.
My laptop uses cosmic + zsh, there everything is working.
My workstation uses Niri + ion, there are issues with gpg.

Finaly I want to use Niri + ion on all my devices.
For testing I run cosmic desktop on my workstation, but same result, nothing works.

.config/ion/initrc

# Starship prompt
eval $(starship init ion)

niri.nix

{ pkgs, lib, config, ... }: {
  options = {
    niriWindowManager.enable = lib.mkEnableOption "enables niri window manager";  
  };

  config = lib.mkIf config.niriWindowManager.enable {
    programs = {
      niri.enable = true;
      waybar.enable = true;
    };

    systemd.user.services.waybar.serviceConfig = {
        Environment = lib.mkForce [ "PATH=/run/current-system/sw/bin"];
    };

    environment.systemPackages = with pkgs; [
      fuzzel
      wl-clipboard
      mako
      grim
      slurp
      swaylock
      nautilus
      swaybg
    ];

    services = {
      gnome.gnome-keyring.enable = true;
      xserver = {
        enable = true;
        xkb.layout = "de";
      };
  
      displayManager.gdm = {
        enable = true;
        wayland = true; 
      };
    };

    security = {
      polkit.enable = true;
      pam.services.swaylock = {};
    };
  };
}

.config/niri/config.kdl

environment {
    NIXOS_OZONE_WL "1"
}

And that’s part of the issue, you need to set gnupg.enable = true; (i.e. actually use the option you created)

You have declared the option (via options... = mkOption ...), now use it!

Alternatively, if you know you’re never going to want to turn the option off, you can skip that whole rigmarole and just have

{ pkgs, ... }: {
  environment.systemPackages = with pkgs; [
    gnupg
    pinentry-curses
  ];

  programs.gnupg.agent = {
    enable = true;
    enableSSHSupport = true;
    pinentryPackage = pkgs.pinentry-curses;
  };
    
  services.dbus.packages = [pkgs.gcr];
  services.pcscd.enable = true;
}

And I would suggest cutting it down even further to start with:

{ pkgs, ... }: {
  programs.gnupg.agent = {
    enable = true;
    pinentryPackage = pkgs.pinentry-curses;
  };
}

Put back individual pieces of the rest of it only as you discover you need them. In particular, I bet the environment.systemPackages part is redundant to the programs.gpg.agent part; pcscd should only be needed if you are intending to keep your GPG keys on a “smart card” or USB security dongle; and enableSSHSupport makes gpg-agent take over ssh-agent’s job, which is something you probably don’t want.

I don’t know what GCR is.