spring-projects/spring-security · error · IllegalArgumentException

SSH key prefix not found

Error message

SSH key prefix not found

What it means

parseSSHPublicKey decodes the base64 payload of an SSH public key and expects the first 11 bytes to equal the 'ssh-rsa ' PREFIX. If the stream is too short or the prefix differs, the data is not a valid SSH-RSA key blob and this IllegalArgumentException is thrown.

Source

Thrown at crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java:234

			writeBigInteger(stream, key.getPublicExponent());
			writeBigInteger(stream, key.getModulus());
		}
		catch (IOException ex) {
			throw new IllegalStateException("Cannot encode key", ex);
		}
		output.append(base64Encode(stream.toByteArray()));
		output.append(" " + id);
		return output.toString();
	}

	private static RSAPublicKey parseSSHPublicKey(String encKey) {
		ByteArrayInputStream in = new ByteArrayInputStream(base64Decode(encKey));

		byte[] prefix = new byte[11];

		try {
			if (in.read(prefix) != 11 || !Arrays.equals(PREFIX, prefix)) {
				throw new IllegalArgumentException("SSH key prefix not found");
			}

			BigInteger e = new BigInteger(readBigInteger(in));
			BigInteger n = new BigInteger(readBigInteger(in));

			return createPublicKey(n, e);
		}
		catch (IOException ex) {
			throw new RuntimeException(ex);
		}
	}

	static RSAPublicKey createPublicKey(BigInteger n, BigInteger e) {
		try {
			return (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(n, e));
		}
		catch (Exception ex) {
			throw new RuntimeException(ex);

View on GitHub (pinned to 96852e8860)

Solutions

  1. Re-copy the complete key line including full base64 body from the original .pub file.
  2. Validate with 'ssh-keygen -l -f keyfile' that the key is intact and RSA.
  3. Ensure the algorithm token in the string matches the embedded blob (both 'ssh-rsa').
  4. Regenerate the key if the file is corrupt: ssh-keygen -t rsa -b 2048.

Example fix

// before
String key = "ssh-rsa AAAATrunc";
RSAPublicKey pk = helper.extractPublicKey(key);
// after
String key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQ...full key...";
RSAPublicKey pk = helper.extractPublicKey(key);
Defensive patterns

Strategy: validation

Validate before calling

boolean isValidSshRsaBlob(String key) {
    String[] p = key.trim().split("\\s+");
    if (p.length < 2 || !p[0].equals("ssh-rsa")) return false;
    try {
        byte[] blob = Base64.getDecoder().decode(p[1]);
        return blob.length >= 11 && new String(blob, 0, 7, StandardCharsets.US_ASCII).equals("ssh-rsa");
    } catch (IllegalArgumentException e) { return false; }
}

Try / catch

try {
    RSAPublicKey pk = helper.extractPublicKey(key);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("prefix not found")) {
        throw new ConfigException("Key body is not a valid ssh-rsa blob; re-copy the full .pub line");
    }
    throw e;
}

Prevention

When it happens

Trigger: extractPublicKey matched the ssh-key regex but the base64 part decodes to bytes that do not start with 'ssh-rsa ' — e.g. truncated key, wrong base64 payload pasted, or an ssh-ed25519 blob's base64 mistakenly paired with a different algorithm token.

Common situations: Manually copying only part of a key from authorized_keys, editors wrapping/truncating long key lines, or mixing algorithm token and body from different keys.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/981aaf119583127a. Report an issue: GitHub.