apache/pulsar · error · IllegalArgumentException
The crypto key reader class %s does not exist
Error message
The crypto key reader class %s does not exist
What it means
validateCryptoKeyReader resolves conf.getCryptoKeyReaderClassName() through a ByteBuddy TypePool; if the named class cannot be found on the classpath (NoSuchTypeException) it throws this IllegalArgumentException. The crypto key reader supplies keys for end-to-end message encryption.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/ValidatorUtils.java:80
return SchemaType.valueOf(schemaTypeOrClassName.toUpperCase());
} catch (IllegalArgumentException e) {
// schemaType is not referring to builtin type
return null;
}
}
public static void validateCryptoKeyReader(CryptoConfig conf, TypePool typePool, boolean isProducer) {
if (isEmpty(conf.getCryptoKeyReaderClassName())) {
return;
}
String cryptoClassName = conf.getCryptoKeyReaderClassName();
TypeDescription cryptoClass = null;
try {
cryptoClass = typePool.describe(cryptoClassName).resolve();
} catch (TypePool.Resolution.NoSuchTypeException e) {
throw new IllegalArgumentException(
String.format("The crypto key reader class %s does not exist", cryptoClassName));
}
if (!cryptoClass.asErasure().isAssignableTo(CryptoKeyReader.class)) {
throw new IllegalArgumentException(
String.format("%s does not implement %s", cryptoClassName, CryptoKeyReader.class.getName()));
}
boolean hasConstructor = cryptoClass.getDeclaredMethods().stream()
.anyMatch(method -> method.isConstructor() && method.getParameters().size() == 1
&& method.getParameters().get(0).getType().asErasure().represents(Map.class));
if (!hasConstructor) {
throw new IllegalArgumentException(
String.format("The crypto key reader class %s does not implement the desired constructor.",
conf.getCryptoKeyReaderClassName()));
}
if (isProducer && (conf.getEncryptionKeys() == null || conf.getEncryptionKeys().length == 0)) {View on GitHub (pinned to 820761864e)
Solutions
- Fix the FQCN in cryptoKeyReaderClassName
- Package the CryptoKeyReader implementation in the submitted function jar
- Avoid shade relocation of the crypto class (keep it outside relocation prefixes) so its name stays stable
Example fix
// before // cryptoKeyReaderClassName: com.acme.shaded.MyKeyReader // relocated name // after // cryptoKeyReaderClassName: com.acme.MyKeyReader // original, packaged in jar
Defensive patterns
Strategy: validation
Validate before calling
try {
Class.forName(cryptoKeyReaderClassName);
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Crypto key reader not in classpath: " + cryptoKeyReaderClassName);
} Try / catch
try {
ValidatorUtils.validateCryptoKeyReader(conf, typePool, isProducer);
} catch (IllegalArgumentException e) {
if (e.getMessage().endsWith("does not exist")) {
// fix FQCN or bundle the class, then resubmit
}
throw e;
} Prevention
- Package the CryptoKeyReader implementation in the function jar
- Exclude the crypto package from shade relocation
- Verify the FQCN via 'jar tf' before submission
When it happens
Trigger: Setting CryptoKeyReaderClassName in ProducerConfig/ConsumerConfig (function crypto conf) to a class absent from the function worker classpath, or a misspelled FQCN.
Common situations: Forgot to bundle custom CryptoKeyReader implementation in the function jar; class relocated by shading so the configured name no longer matches; typo when writing the function yaml/CLI flag.
Related errors
- Unable to initialize crypto config %s
- The schema class %s does not exist
- The message payload processor class %s does not exist
- Config class not found: %s
- CryptoKeyReader class name required
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/7247e0bd40023fae.
Report an issue: GitHub.