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

  1. Split the file so it contains exactly one private key, and pass that file via -i.
  2. If you have several keys, pass each with its own -i flag rather than concatenating them.
  3. 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

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


AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14). Data as JSON: /api/errors/b50957bb006f7e01. Report an issue: GitHub.