No such file or directory with script in systemd service

Either in an ISO or on a new system, I’m getting a No such file or directory error with a systemd service script or ExecStart. Here is one of the services:

# TODO: Can I move these to the `onChange' attribute?
{
  config,
  lib,
  pkgs,
  ...
}:
{
  imports = lib.syvl.import.all ./. { };
  systemd.services = lib.mapAttrs' (
    User: info:
    lib.nameValuePair "${User}-age-host-keys" {
      description = "create age host keys for ${User}";
      wantedBy = [ "multi-user.target" ];
      requiredBy = [ "sysinit-reactivation.target" ];
      before = [ "sysinit-reactivation.target" ];
      after = [ "systemd-sysusers.service" ];
      serviceConfig = {
        Type = "oneshot";
        ExecStart =
          let
            etcPath = config.flake.paths.etc.nixos.path;
            script = pkgs.writeShellApplication {
              name = "${User}-age-home-manager-create-keys";
              runtimeInputs = with pkgs; [
                age
              ];
              excludeShellChecks = [
                "SC2319"
              ];
              text = ''
                [[ -d "${etcPath}" ]] && [[ -n "$(ls -A "${etcPath}")" ]]
                etcPathExists=$?

                if [[ $etcPathExists -eq 0 ]]; then
                  chown -R ${builtins.toString config.flake.paths.etc.nixos.user.uid}:${builtins.toString config.flake.paths.etc.nixos.group.gid} ${etcPath}
                  etcRoot="${config.flake.paths.etc.host}/users/${User}"
                  etcAge="''${etcRoot}/.age"
                  mkdir -p "$etcAge"
                  chmod 700 "$etcAge"
                fi

                ageDirectory="${info.home}/.age"
                mkdir -p "$ageDirectory"
                chmod 700 "$ageDirectory"
                chown ${User}:${info.group} "$ageDirectory"

                id="''${ageDirectory}/id"
                pubkey="$(basename "$id").pub"
                if [[ ! -s "$id" ]]; then
                  agePubkey="''${ageDirectory}/''${pubkey}"
                  rm "$agePubkey" 2> /dev/null || :
                  age-keygen -o "$id"
                  age-keygen -y "$id" > "$agePubkey"
                  chown ${User}:${info.group} "$id"
                  chown ${User}:${info.group} "$agePubkey"
                fi

                if [[ $etcPathExists -eq 0 ]]; then
                  age-keygen -y "$id" > "''${etcAge}/''${pubkey}"
                  chown -R ${User}:${info.group} "$etcRoot"
                fi
              '';
            };
          in
          lib.getExe script;
      };
    }
  ) config.users.loginUsers;
}

Systemd services don’t inherit the $PATH set by environment.systemPackages. Add your script’s dependencies to NixOS Search

Sorry, I meant the script itself apparently isn’t being found.

How does the generated unit and scripts look like and what is the very exact error you get?

1 Like

Right, also my bad, I see the runtimeInputs on second read. Listen to @NobbZ, he’s more conscious.

1 Like

Well this is interesting… It seems to be pointing to an older script:

[Unit]
After=systemd-sysusers.service
Before=sysinit-reactivation.target
Description=create age host keys for syvlorg

[Service]
Environment="LOCALE_ARCHIVE=/nix/store/gh4lla9695vv6ich99i63pz8pying61n-glibc-locales-2.42-61/lib/locale/locale-archive"
Environment="PATH=/nix/store/ipcrbbd4c60cdf5wrx5zw6z3a8f0p4cp-age-1.3.1/bin:/nix/store/bcnisk3ydfgv26v2gw3zlky24g00yww2-git-2.54.0/bin:/nix/store/0dnhgpmqy39brwjb92sfmwdsnb1ggw79-xonsh-0.23.7/bin:/nix/store/9ypz3flqsrl5xl495mm8h645gadjsxi1-coreutils-9.11/bin:/nix/store/c1cjgg6p8m8fssivzrc2p13mwwml3p3v-findutils-4.10.0/bin:/nix/store/gn94gpcp5q08x4v6g8mvw8v4r65rcjzk-gnugrep-3.12/bin:/nix/store/kgxafhycw2kybbqih759ykc2043qyi5j-gnused-4.9/bin:/nix/store/a8avqfxd649rfgfpqldja6v38ljb8fj5-systemd-260.1/bin:/nix/store/ipcrbbd4c60cdf5wrx5zw6z3a8f0p4cp-age-1.3.1/sbin:/nix/store/bcnisk3ydfgv26v2gw3zlky24g00yww2-git-2.54.0/sbin:/nix/store/0dnhgpmqy39brwjb92sfmwdsnb1ggw79-xonsh-0.23.7/sbin:/nix/store/9ypz3flqsrl5xl495mm8h645gadjsxi1-coreutils-9.11/sbin:/nix/store/c1cjgg6p8m8fssivzrc2p13mwwml3p3v-findutils-4.10.0/sbin:/nix/store/gn94gpcp5q08x4v6g8mvw8v4r65rcjzk-gnugrep-3.12/sbin:/nix/store/kgxafhycw2kybbqih759ykc2043qyi5j-gnused-4.9/sbin:/nix/store/a8avqfxd649rfgfpqldja6v38ljb8fj5-systemd-260.1/sbin"
Environment="TZDIR=/nix/store/v2hsfkf03b3l79rhcxw4nq7w79kr3qkw-tzdata-2026b/share/zoneinfo"
ExecStart=/nix/store/vkwy5acaldaf5rixqpfi00qn81ayb49i-syvlorg-age-home-manager-create-keys
Type=oneshot

[Install]
WantedBy=multi-user.target
× syvlorg-age-host-keys.service - create age host keys for syvlorg
     Loaded: loaded (/etc/systemd/system/syvlorg-age-host-keys.service; enabled; preset: ignored)
     Active: failed (Result: exit-code) since Fri 2026-05-29 09:41:05 EDT; 2min 42s ago
 Invocation: dc27ca6f27674965834160cd92e95102
    Process: 1981 ExecStart=/nix/store/vkwy5acaldaf5rixqpfi00qn81ayb49i-syvlorg-age-home-manager-create-keys (code=exited, status=203/EXEC)
   Main PID: 1981 (code=exited, status=203/EXEC)
         IP: 0B in, 0B out
         IO: 348K read, 0B written
   Mem peak: 3M
        CPU: 12ms

May 29 09:41:05 iso systemd[1]: Starting create age host keys for syvlorg...
May 29 09:41:05 iso (vkwy5acaldaf5rixqpfi00qn81ayb49i-syvlorg-age-home-manager-create-keys)[1981]: syvlorg-age-host-keys.service: Failed to execute /nix/store/vkwy5acaldaf5rixqpfi00qn81ayb49i-syvlorg-age-home-manager-create-keys: No such file or directory
May 29 09:41:05 iso (vkwy5acaldaf5rixqpfi00qn81ayb49i-syvlorg-age-home-manager-create-keys)[1981]: syvlorg-age-host-keys.service: Failed at step EXEC spawning /nix/store/vkwy5acaldaf5rixqpfi00qn81ayb49i-syvlorg-age-home-manager-create-keys: No such file or directory
May 29 09:41:05 iso systemd[1]: syvlorg-age-host-keys.service: Main process exited, code=exited, status=203/EXEC
May 29 09:41:05 iso systemd[1]: syvlorg-age-host-keys.service: Failed with result 'exit-code'.
May 29 09:41:05 iso systemd[1]: Failed to start create age host keys for syvlorg.
#! /usr/bin/env xonsh

$XONSH_SHOW_TRACEBACK = True
$RAISE_SUBPROC_ERROR = True

import os, random, time
from pathlib import Path

etcPath = Path("/home/syvlorg/nixos")
etcPathExists = etcPath.exists() and any(etcPath.iterdir())
if etcPathExists:
  chown -R 43628:43628 @(etcPath)

  etcRoot = Path("/home/syvlorg/nixos/systems/x86_64-linux/iso/users/syvlorg")
  etcAge = etcRoot / ".age"
  etcAge.mkdir(mode=0o700, parents=True, exist_ok=True)

ageDirectory = Path("/home/syvlorg/.age")
ageDirectory.mkdir(mode=0o700, parents=True, exist_ok=True)
chown syvlorg:syvlorg @(ageDirectory)

id = ageDirectory / "id"
pubkey = f"{id.name}.pub"
if not id.exists():
  agePubkey = ageDirectory / pubkey
  agePubkey.unlink(missing_ok=True)
  age-keygen -o @(id)
  age-keygen -y @(id) > @(agePubkey)
  chown syvlorg:syvlorg @(id)
  chown syvlorg:syvlorg @(agePubkey)

if etcPathExists:
  etcPubkey = etcAge / pubkey
  age-keygen -y @(id) > @(etcPubkey)

  chown -R syvlorg:syvlorg @(etcRoot)

And I swear I rebuilt it. Here’s the ISO host-specific config:

{
  config,
  lib,
  modulesPath,
  rootPath,
  ...
}:
{
  imports = [
    (modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix")
    "${rootPath}/common/specialisations/desktop-environments/gnome"
  ];

  # preservation.enable = mkForce false;

  # Adapted From: https://nixos.wiki/wiki/Remote_Desktop#Using_XRDP
  services.getty.autologinUser =
    let
      cfg = config.services.displayManager.autoLogin;
    in
    lib.mkIf (cfg.enable) (lib.mkForce cfg.user);
}

I deleted the last ISO and am currently rebuilding again, just in case.

Are you sure your most recent version was activated successfully?

The most recent ISO version? How can I ensure that?

If in doubt, can you share a minimal repo that we can build a system or the ISO from to check?

Depends on how minimal. Do you want just the systemd services and everything necessary for them to work? My config tend to get a bit complicated, unfortunately.

A SSCCE/MWE is prefered, if though your (or the config you try to do this in) is public, then share that.

Though I often realized, that in the process of creating a MWE, one finds the actual problem.

1 Like

I’ll try and create the MWE, then; in the meantime, however, here is the repo. I think the cause is most likely due to the preservation module, but I’m trying to figure out if it only happens in ISOs or new systems as well.

Hmm. Does rebuilding without deleting the old ISO file not work? I thought the new ISO replaced the old one? Seemed to have been working fine for me before… Unless rsync isn’t detecting any changes to the ISO and not copying it over…

Okay, new problem. While the new scripts are working now after deleting the old result, this systemd service is now exiting with code 1 but without an error. How can I debug this without having to constantly rebuild the ISO? It takes time and may be starting to damage my USB drive.

Spin up a VM with the ISO instead? Without having looked further at your repository, nixos-rebuild build-vm might help, too.

1 Like

Thought that might be the case. nixos-rebuild build-vm would only work for the current host, right? Or can I just set the uri to the ISO host and my current system would be unaffected?

You can change the configuration you’re building with nixos-rebuild build-vm -I nixos-config=/some/path/to/a/configuration.nix (or you can use --flake /some/path/to/a/directory/containing/a/flake.nix/but/not/the/file/itself/, of course).

It does not affect your running system.

1 Like

Got it. I’ll insert some echos and see where it falls, then report back.

Found the problem with the services: set -o errexit forced the service to fail if the NixOS repo didn’t exist. I disabled it around that block and added || : as appropriate everywhere else. The services are working perfectly now. Still don’t know why the scripts weren’t being found initially, but I’ll assume it’s because the ISO wasn’t being updated either by nix build or rsync. Thanks for all the help, @TLATER and @NobbZ!

1 Like