phacility/phabricator · error · PhutilProxyException
Failed to convert public key into PKCS8 format. If you are d
Error message
Failed to convert public key into PKCS8 format. If you are developing on OSX, you may be able to use `%s` to work around this issue. %s
What it means
PhabricatorAuthSSHPublicKey::getPKCS8Key() first tries the cache, then writes the key to a TempFile and runs 'ssh-keygen -e -m PKCS8 -f <tmp>' to re-encode it. If execx() raises a CommandException, it is wrapped in a PhutilProxyException whose message suggests 'bin/auth cache-pkcs8' as an OSX workaround and embeds the underlying ssh-keygen error.
Source
Thrown at src/applications/auth/sshkey/PhabricatorAuthSSHPublicKey.php:129
public function toPKCS8() {
$entire_key = $this->getEntireKey();
$cache_key = $this->getPKCS8CacheKey($entire_key);
$cache = PhabricatorCaches::getImmutableCache();
$pkcs8_key = $cache->getKey($cache_key);
if ($pkcs8_key) {
return $pkcs8_key;
}
$tmp = new TempFile();
Filesystem::writeFile($tmp, $this->getEntireKey());
try {
list($pkcs8_key) = execx(
'ssh-keygen -e -m PKCS8 -f %s',
$tmp);
} catch (CommandException $ex) {
unset($tmp);
throw new PhutilProxyException(
pht(
'Failed to convert public key into PKCS8 format. If you are '.
'developing on OSX, you may be able to use `%s` '.
'to work around this issue. %s',
'bin/auth cache-pkcs8',
$ex->getMessage()),
$ex);
}
unset($tmp);
$cache->setKey($cache_key, $pkcs8_key);
return $pkcs8_key;
}
public function forcePopulatePKCS8Cache($pkcs8_key) {
$entire_key = $this->getEntireKey();
$cache_key = $this->getPKCS8CacheKey($entire_key);View on GitHub (pinned to 5720a38cfe)
Solutions
- Run the documented workaround: './bin/auth cache-pkcs8' to precompute and store PKCS8 key bodies in the cache
- Install a real OpenSSH build earlier in PATH (e.g. brew install openssh on macOS) so system ssh-keygen honors '-m PKCS8'
- Inspect the chained CommandException message (getPrevious()) for the exact ssh-keygen stderr to confirm the cause
Example fix
# before $ echo test | ssh-keygen -e -m PKCS8 -f /dev/stdin # wrong/copy output on OSX ssh-keygen # after $ brew install openssh $ /usr/local/opt/openssh/bin/ssh-keygen -e -m PKCS8 -f ./id_ed25519.pub # valid PKCS8 $ ./bin/auth cache-pkcs8
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-warm the cache so runtime conversion never needs ssh-keygen: // run once during deploy on a host with a known-good ssh-keygen: // ./bin/auth cache-pkcs8 // Then getPKCS8Key() hits the cache and never shells out.
Try / catch
try {
$pkcs8 = $public_key->getPKCS8Key();
} catch (PhutilProxyException $ex) {
$cause = $ex->getPrevious(); // CommandException: real ssh-keygen stderr
// Fallback: precompute via './bin/auth cache-pkcs8', or point PATH
// at a real OpenSSH ssh-keygen build, then retry.
} Prevention
- Run 'bin/auth cache-pkcs8' after initial setup on OSX hosts - it is the documented workaround
- Verify 'ssh-keygen -e -m PKCS8 -f somekey.pub' produces -----BEGIN PUBLIC KEY----- output on hosts doing conversion
- Treat conversion failures as environment issues first (vendor ssh-keygen), key issues second
When it happens
Trigger: The system ssh-keygen cannot re-encode the stored key into PKCS8 - classically macOS's bundled ssh-keygen (LibreSSL-era) that ignores '-m PKCS8' and emits RFC4716 instead, or a key body that passed storage validation but fails conversion on the host doing the conversion.
Common situations: Development installs on OSX hitting this on first PKCS8 conversion before any cache entry exists; hosts where /usr/bin/ssh-keygen is a vendor build with different '-m' behavior; SSH trust/cluster communication setups that need PKCS8 forms.
Related errors
- This public key is already associated with another user or d
- Analyzing or decrypting SSH keys requires the "ssh-keygen" b
- No public key was provided.
- Provide a public key, not a private key!
- Provided public key is not properly formatted.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/a5e054d36801040f.
Report an issue: GitHub.