phacility/phabricator · error · PhutilArgumentUsageException
No private key exists at path "%s"!
Error message
No private key exists at path "%s"!
What it means
Usage exception from `bin/almanac register`: --private-key was provided but no file exists at that path (Filesystem::pathExists check). The path is then handed to Filesystem::readFile, so the workflow fails fast with a readable message instead of a raw I/O error.
Source
Thrown at src/applications/almanac/management/AlmanacManagementRegisterWorkflow.php:79
$identity_device = id(new AlmanacDeviceQuery())
->setViewer($viewer)
->withNames(array($raw_device))
->executeOne();
if (!$identity_device) {
throw new PhutilArgumentUsageException(
pht(
'No such device "%s" exists!', $raw_device));
}
$private_key_path = $args->getArg('private-key');
if (!strlen($private_key_path)) {
throw new PhutilArgumentUsageException(
pht('Specify a private key with --private-key.'));
}
if (!Filesystem::pathExists($private_key_path)) {
throw new PhutilArgumentUsageException(
pht('No private key exists at path "%s"!', $private_key_path));
}
$raw_private_key = Filesystem::readFile($private_key_path);
$phd_user = PhabricatorEnv::getEnvConfig('phd.user');
if (!$phd_user) {
throw new PhutilArgumentUsageException(
pht(
'Config option "phd.user" is not set. You must set this option '.
'so the private key can be stored with the correct permissions.'));
}
$tmp = new TempFile();
list($err) = exec_manual('chown %s %s', $phd_user, $tmp);
if ($err) {
throw new PhutilArgumentUsageException(
pht(View on GitHub (pinned to 5720a38cfe)
Solutions
- Check the path character by character and use an absolute path for --private-key.
- If generating the key in automation, add an explicit existence check (and chmod 600) between generation and register.
- Confirm mounts/permissions when running under sudo or inside containers.
Example fix
# before $ bin/almanac register --device web-001 --private-key ./device.key Usage Exception: No private key exists at path "./device.key"! # after $ ls -l /root/.ssh/device.key $ bin/almanac register --device web-001 --private-key /root/.ssh/device.key
Defensive patterns
Strategy: validation
Validate before calling
$key = '/root/.ssh/device.key'; // always absolute
if (!file_exists($key)) {
throw new RuntimeException("Private key not found at '{$key}'");
}
// invoke: bin/almanac register --device X --private-key $key Prevention
- Use absolute paths for --private-key, especially under sudo/cron/containers.
- Order automation: generate key -> verify exists -> register.
- Fail provisioning loudly when the key artifact is absent instead of letting the CLI discover it.
When it happens
Trigger: Typo'd path, e.g. /root/id_deivce; relative path evaluated from a different working directory than expected; key on a volume not mounted in the provisioning environment; script step ordering where register runs before the key is written.
Common situations: Relative paths in cron/daemon contexts where cwd is not the shell's cwd; keys generated as another user with a home path that differs under sudo; race conditions in infrastructure automation.
Related errors
- Specify a private key with --private-key.
- This host already has a registered public key ("%s"). Remove
- This host already has a registered private key ("%s"). Remov
- The public key corresponding to the given private key is unk
- The public key corresponding to the given private key is alr
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/683d9bf30c4cc80e.
Report an issue: GitHub.