phacility/phabricator · error · Exception
Only private key credentials are supported.
Error message
Only private key credentials are supported.
What it means
Thrown by DrydockSFTPFilesystemInterface when the credential configured for an SFTP interface is not an SSH private key credential. The interface loads the credential by ID from blueprint/lease config (getConfig('credential')), requires its secrets, and checks getProvidesType() against PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE because the sftp command line is assembled with a private key file (-i). Any other Passphrase credential type (password, token, etc.) is rejected.
Source
Thrown at src/applications/drydock/interface/filesystem/DrydockSFTPFilesystemInterface.php:20
final class DrydockSFTPFilesystemInterface extends DrydockFilesystemInterface {
private $passphraseSSHKey;
private function openCredentialsIfNotOpen() {
if ($this->passphraseSSHKey !== null) {
return;
}
$credential = id(new PassphraseCredentialQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withIDs(array($this->getConfig('credential')))
->needSecrets(true)
->executeOne();
if ($credential->getProvidesType() !==
PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE) {
throw new Exception(pht('Only private key credentials are supported.'));
}
$this->passphraseSSHKey = PassphraseSSHKey::loadFromPHID(
$credential->getPHID(),
PhabricatorUser::getOmnipotentUser());
}
private function getExecFuture($path) {
$this->openCredentialsIfNotOpen();
return new ExecFuture(
'sftp -o "StrictHostKeyChecking no" -P %s -i %P %P@%s',
$this->getConfig('port'),
$this->passphraseSSHKey->getKeyfileEnvelope(),
$this->passphraseSSHKey->getUsernameEnvelope(),
$this->getConfig('host'));
}
View on GitHub (pinned to 5720a38cfe)
Solutions
- Create an SSH private key credential in Passphrase (type 'ssh-key' / provides type of PassphraseSSHPrivateKeyCredentialType) containing the key used to authenticate to the SFTP host.
- Update the blueprint's credential config (the 'credential' key, a credential ID) to the new credential's ID and re-acquire the lease/resource.
- Verify the choice programmatically: load the credential and assert getProvidesType() matches PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE before configuring.
Example fix
// before: blueprint 'credential' config points at a password credential
// (PassphraseSSHPasswordCredentialType) -> throws
// after: create an ssh-key credential, e.g.
// passphrase.credential.create with type 'ssh-key', then
$this->setConfig('credential', $ssh_key_credential->getID()); Defensive patterns
Strategy: validation
Validate before calling
$credential = id(new PassphraseCredentialQuery())
->setViewer($viewer)
->withIDs(array($credential_id))
->executeOne();
if (!$credential ||
$credential->getProvidesType() !==
PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE) {
throw new InvalidArgumentException(
'SFTP interfaces require an SSH private key credential.');
} Type guard
function isSSHKeyCredential(PassphraseCredential $credential) {
return $credential->getProvidesType()
=== PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE;
} Prevention
- Adopt a naming convention for credentials (e.g. prefix 'ssh-') so key credentials are distinguishable at a glance.
- Validate the credential type in blueprint configuration UI/scripts before any lease is acquired, not at first SFTP use.
When it happens
Trigger: A host blueprint or lease declares an SFTP filesystem interface whose 'credential' config points at a Passphrase credential of the wrong provides-type (e.g. a password credential or an SSH public key). The first call to openCredentialsIfNotOpen()/getExecFuture() throws before any sftp command runs.
Common situations: Reusing an existing generic/password credential instead of creating an SSH key credential; pasting a credential ID from another blueprint without checking its type; rotating credentials and replacing the SSH key credential with a different type under the same name.
Related errors
- Unable to load API token ("%s")!
- Attempting to use a credential ("%s") but the credential sec
- Specify a private key with --private-key.
- No private key exists at path "%s"!
- This host already has a registered public key ("%s"). Remove
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/1b1c02cc60cb74a5.
Report an issue: GitHub.