jenkinsci/jenkins · error · InvalidKeySpecException
Multiple private key pairs N/A: key
Error message
Multiple private key pairs N/A: key
What it means
InvalidKeySpecException thrown by PrivateKeyProvider.loadKey when loadKeyPairIdentities returns more than one key pair from a single PEM input. The CLI expects exactly one private key per -i file, so multiple identities are ambiguous and rejected.
Source
Thrown at cli/src/main/java/hudson/cli/PrivateKeyProvider.java:154
byte[] bytes = new byte[(int) f.length()];
dis.readFully(bytes);
return new String(bytes, StandardCharsets.UTF_8);
} catch (InvalidPathException e) {
throw new IOException(e);
}
}
public static KeyPair loadKey(String pemString, String passwd) throws IOException, GeneralSecurityException {
Iterable<KeyPair> itr = SecurityUtils.loadKeyPairIdentities(null,
new PathResource(Paths.get("key")),
new ByteArrayInputStream(pemString.getBytes(StandardCharsets.UTF_8)),
FilePasswordProvider.of(passwd));
long numLoaded = itr == null ? 0 : StreamSupport.stream(itr.spliterator(), false).count();
if (numLoaded <= 0) {
throw new InvalidKeyException("Unsupported private key file format: key");
}
if (numLoaded != 1) {
throw new InvalidKeySpecException("Multiple private key pairs N/A: key");
}
return itr.iterator().next();
}
private static final Logger LOGGER = Logger.getLogger(PrivateKeyProvider.class.getName());
}
View on GitHub (pinned to 2e228ff40b)
Solutions
- Split the file so it contains exactly one private key, and pass that file via -i.
- If you have several keys, pass each with its own -i flag rather than concatenating them.
- Re-generate a single key if the file is an accidental concatenation.
Example fix
# before: id_rsa holds two PEM blocks java -jar jenkins-cli.jar -i id_rsa -s http://j ... # after java -jar jenkins-cli.jar -i id_rsa_only -s http://j ...
Defensive patterns
Strategy: validation
Validate before calling
// Count PEM private-key blocks; reject multi-key files up front
long count = pem.lines().filter(l -> l.contains("-----BEGIN") && l.contains("PRIVATE KEY-----")).count();
if (count != 1) {
throw new IllegalArgumentException("Expected exactly one private key, found " + count);
} Try / catch
try {
PrivateKeyProvider.loadKey(pem, passwd);
} catch (InvalidKeySpecException e) {
// split the file and pass keys individually with separate -i flags
} Prevention
- Keep one private key per file.
- Pass multiple keys as separate -i arguments rather than concatenating.
- Inspect concatenated key files before reuse.
When it happens
Trigger: A key file contains concatenated multiple private key blocks, or a format the SSHD parser expands into several identities.
Common situations: User concatenated several keys into one file; an SSH agent export; a PEM bundle containing a chain of private keys.
Related errors
- Unsupported private key file format: key
- Failed to retrieve command result in time: {}
- Unknown public key type:
- There's no Jenkins running at {}
- expected to see initial zero byte; perhaps you are connectin
AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14).
Data as JSON: /api/errors/b50957bb006f7e01.
Report an issue: GitHub.