grpc/grpc-java · error · IllegalArgumentException
'kty' parameter must be one of %s but '%s' found. Certificat
Error message
'kty' parameter must be one of %s but '%s' found. Certificate loading for trust domain '%s' failed.
What it means
SpiffeUtil.checkJwkEntry validates each JWK in a SPIFFE trust bundle. The 'kty' (key type) parameter must be one of the accepted values (e.g. RSA or EC); a missing or unrecognized kty makes the key unusable for X.509-SVID verification, so an IllegalArgumentException naming the trust domain is thrown.
Source
Thrown at core/src/main/java/io/grpc/internal/SpiffeUtil.java:210
String json = new String(Files.toByteArray(file), StandardCharsets.UTF_8);
Object jsonObject = JsonParser.parse(json);
if (!(jsonObject instanceof Map)) {
throw new IllegalArgumentException(
"SPIFFE Trust Bundle should be a JSON object. Found: "
+ (jsonObject == null ? null : jsonObject.getClass()));
}
@SuppressWarnings("unchecked")
Map<String, ?> root = (Map<String, ?>)jsonObject;
Map<String, ?> trustDomainsNode = JsonUtil.getObject(root, "trust_domains");
checkNotNull(trustDomainsNode, "Mandatory trust_domains element is missing");
checkArgument(trustDomainsNode.size() > 0, "Mandatory trust_domains element is missing");
return trustDomainsNode;
}
private static void checkJwkEntry(Map<String, ?> jwkNode, String trustDomainName) {
String kty = JsonUtil.getString(jwkNode, "kty");
if (kty == null || !KTY_PARAMETER_VALUES.contains(kty)) {
throw new IllegalArgumentException(
String.format(
"'kty' parameter must be one of %s but '%s' "
+ "found. Certificate loading for trust domain '%s' failed.",
KTY_PARAMETER_VALUES, kty, trustDomainName));
}
if (jwkNode.containsKey("kid")) {
throw new IllegalArgumentException(String.format("'kid' parameter must not be set. "
+ "Certificate loading for trust domain '%s' failed.", trustDomainName));
}
String use = JsonUtil.getString(jwkNode, "use");
if (use == null || !use.equals(USE_PARAMETER_VALUE)) {
throw new IllegalArgumentException(String.format("'use' parameter must be '%s' but '%s' "
+ "found. Certificate loading for trust domain '%s' failed.", USE_PARAMETER_VALUE,
use, trustDomainName));
}
}
private static List<X509Certificate> extractCert(List<Map<String, ?>> keysNode,View on GitHub (pinned to 64daddc1f3)
Solutions
- Set kty to a supported value — "RSA" or "EC" — matching the actual key material
- Remove oct (symmetric) keys from the trust bundle; SPIFFE X.509 bundles contain only public asymmetric keys
- Fix casing/spelling: kty values are exact-case per RFC 7517 ("RSA", not "rsa" or "RS256")
- Regenerate the bundle from SPIRE (spire-agent api fetch x509-bundle) rather than hand-editing
Example fix
// before
{"use":"x509-svid","kty":"rsa","n":"..."}
// after
{"use":"x509-svid","kty":"RSA","n":"..."} Defensive patterns
Strategy: validation
Validate before calling
// Pre-check every JWK's kty
for (Map<String, ?> key : keys) {
String kty = (String) key.get("kty");
if (!"RSA".equals(kty) && !"EC".equals(kty)) {
throw new IllegalStateException("JWK kty must be RSA or EC, got: " + kty);
}
} Type guard
boolean hasSupportedKty(Map<String, ?> jwk) {
Object kty = jwk.get("kty");
return "RSA".equals(kty) || "EC".equals(kty);
} Try / catch
try {
certs = SpiffeUtil.loadTrustBundleFromFile(bundlePath);
} catch (IllegalArgumentException e) {
log.error("Trust bundle JWK rejected: " + e.getMessage());
throw new TrustBundleLoadException(e);
} Prevention
- Exclude symmetric (oct) keys from trust bundles
- Keep exact-case kty values per RFC 7517
- Regenerate bundles with SPIRE tooling instead of hand-editing
When it happens
Trigger: Loading a trust bundle whose JWK entry lacks 'kty' or has a kty outside KTY_PARAMETER_VALUES (e.g. "oct" for symmetric keys, or a lowercase/misspelled value like "rsa"), via extractCert during bundle loading.
Common situations: Hand-built bundles with keys exported from JWKS endpoints that include oct keys; manually trimmed JWKs missing required fields; typos like "RSA " or "RS256" mistakenly placed in kty.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- 'use' parameter must be '%s' but '%s' found. Certificate loa
- 'kid' parameter must not be set. Certificate loading for tru
- SPIFFE Trust Bundle should be a JSON object. Found: ${type}
- Certificate can't be parsed. Certificate loading for trust d
- "key" is absent or empty
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/b58774a3776c2c84.
Report an issue: GitHub.