apache/pulsar · error · IllegalArgumentException
Invalid value for BROKER_CLIENT_TRUST_CERTS_SECRET_NAME. Exp
Error message
Invalid value for BROKER_CLIENT_TRUST_CERTS_SECRET_NAME. Expected a string.
What it means
KubernetesServiceAccountTokenAuthProvider.initialize() validates the function auth config map. If BROKER_CLIENT_TRUST_CERTS_SECRET_NAME is set to a non-String, non-null value (e.g. an Integer, Boolean or Map), the provider deliberately fails fast with IllegalArgumentException because the user explicitly configured this key but with an invalid type.
Source
Thrown at pulsar-functions/runtime/src/main/java/org/apache/pulsar/functions/auth/KubernetesServiceAccountTokenAuthProvider.java:87
private static final String DEFAULT_MOUNT_DIR = "/etc/auth";
private static final String FUNCTION_AUTH_TOKEN = "token";
private static final String FUNCTION_CA_CERT = "ca.crt";
private static final String DEFAULT_CERT_PATH = DEFAULT_MOUNT_DIR + "/" + FUNCTION_CA_CERT;
private String brokerTrustCertsSecretName;
private long serviceAccountTokenExpirationSeconds;
private String serviceAccountTokenAudience;
@Override
public void initialize(CoreV1Api coreClient, byte[] caBytes,
java.util.function.Function<FunctionDetails, String> namespaceCustomizerFunc,
Map<String, Object> config) {
setNamespaceProviderFunc(namespaceCustomizerFunc);
Object certSecretName = config.get(BROKER_CLIENT_TRUST_CERTS_SECRET_NAME);
if (certSecretName instanceof String) {
brokerTrustCertsSecretName = (String) certSecretName;
} else if (certSecretName != null) {
// Throw exception because user set this configuration, but it isn't valid.
throw new IllegalArgumentException("Invalid value for " + BROKER_CLIENT_TRUST_CERTS_SECRET_NAME
+ ". Expected a string.");
}
Object tokenExpirationSeconds = config.get(SERVICE_ACCOUNT_TOKEN_EXPIRATION_SECONDS);
if (tokenExpirationSeconds instanceof Long) {
serviceAccountTokenExpirationSeconds = (Long) tokenExpirationSeconds;
} else if (tokenExpirationSeconds instanceof String) {
try {
serviceAccountTokenExpirationSeconds = Long.parseLong((String) tokenExpirationSeconds);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid value for " + SERVICE_ACCOUNT_TOKEN_EXPIRATION_SECONDS
+ ". Expected a long.");
}
} else if (tokenExpirationSeconds != null) {
// Throw exception because user set this configuration, but it isn't valid.
throw new IllegalArgumentException("Invalid value for " + SERVICE_ACCOUNT_TOKEN_EXPIRATION_SECONDS
+ ". Expected a long.");
}
Object tokenAudience = config.get(SERVICE_ACCOUNT_TOKEN_AUDIENCE);View on GitHub (pinned to 820761864e)
Solutions
- Set BROKER_CLIENT_TRUST_CERTS_SECRET_NAME to a quoted String value containing the Kubernetes secret name.
- Check the config source (YAML/JSON/env parser) and quote or coerce values so numeric-looking names arrive as strings.
- Log/inspect the exact config value and its Java class before calling initialize to find where the wrong type enters.
Example fix
// before config.put(BROKER_CLIENT_TRUST_CERTS_SECRET_NAME, 12345); // after config.put(BROKER_CLIENT_TRUST_CERTS_SECRET_NAME, String.valueOf(12345));
Defensive patterns
Strategy: validation
Validate before calling
Object v = config.get(BROKER_CLIENT_TRUST_CERTS_SECRET_NAME);
if (v != null && !(v instanceof String)) {
throw new IllegalArgumentException("BROKER_CLIENT_TRUST_CERTS_SECRET_NAME must be a String, got " + v.getClass().getName());
} Type guard
static boolean isStringConfig(Object v) { return v == null || v instanceof String; } Try / catch
try {
provider.initialize(config);
} catch (IllegalArgumentException e) {
log.error("Function auth provider config invalid: {}", e.getMessage());
throw new ConfigValidationException(e);
} Prevention
- Quote string values in YAML/JSON configs even if they look numeric
- Validate config maps against an expected key->type schema before passing to the provider
- Add unit tests for config loading that assert value types
- Log config value classes at debug when building the auth config
When it happens
Trigger: Calling initialize(authConfig) where config.get(BROKER_CLIENT_TRUST_CERTS_SECRET_NAME) returns a non-null object that is not a String — e.g. the config was built programmatically with a number, boolean, or nested collection instead of a secret name string.
Common situations: YAML/JSON tooling parsed the secret name as a number or boolean (e.g. `12345` or `true` unquoted); a config builder passed a wrong-typed value; configuration deserialization coerced the value to an unexpected type.
Related errors
- Invalid value for SERVICE_ACCOUNT_TOKEN_EXPIRATION_SECONDS.
- Invalid value for SERVICE_ACCOUNT_TOKEN_AUDIENCE. Expected a
- Failed to create service for function %s
- Failed to create statefulset for function %s
- Failed to delete statefulset for function %s
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/b96b1969bf0ce5e6.
Report an issue: GitHub.