apache/pulsar · error · RuntimeException
Invalid Fully Qualified Function Name
Error message
Invalid Fully Qualified Function Name
What it means
FunctionCommon's fully-qualified function name (FQFN) helpers expect the canonical 'tenant/namespace/functionName' format with at least three '/'-separated parts. extractFromFullyQualifiedName throws this RuntimeException when the input string has fewer than three parts, i.e. it is not a valid FQFN.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionCommon.java:350
public static String extractTenantFromFullyQualifiedName(String fqfn) {
return extractFromFullyQualifiedName(fqfn, 0);
}
public static String extractNamespaceFromFullyQualifiedName(String fqfn) {
return extractFromFullyQualifiedName(fqfn, 1);
}
public static String extractNameFromFullyQualifiedName(String fqfn) {
return extractFromFullyQualifiedName(fqfn, 2);
}
private static String extractFromFullyQualifiedName(String fqfn, int index) {
String[] parts = fqfn.split("/");
if (parts.length >= 3) {
return parts[index];
}
throw new RuntimeException("Invalid Fully Qualified Function Name " + fqfn);
}
public static double roundDecimal(double value, int places) {
double scale = Math.pow(10, places);
return Math.round(value * scale) / scale;
}
public static String capFirstLetter(Enum<?> en) {
return StringUtils.capitalize(en.toString().toLowerCase());
}
public static boolean isFunctionCodeBuiltin(
FunctionDetails functionDetail) {
return isFunctionCodeBuiltin(functionDetail, functionDetail.getComponentType());
}
public static boolean isFunctionCodeBuiltin(
FunctionDetails functionDetails,View on GitHub (pinned to 820761864e)
Solutions
- Ensure the string has the form tenant/namespace/functionName before calling the extractors
- Build the FQFN from components with FunctionCommon.getFullyQualifiedName(tenant, namespace, name) when you only have parts
- Add a precondition check (split('/') >= 3) in your calling code and produce a clearer error message
- Verify the input is a function FQFN and not a topic or connector name
Example fix
// before String name = "my-function"; String tenant = FunctionCommon.extractTenantFromFullyQualifiedName(name); // throws // after String name = "public/default/my-function"; String tenant = FunctionCommon.extractTenantFromFullyQualifiedName(name); // "public"
Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate FQFN shape
boolean validFqfn(String fqfn) {
String[] parts = fqfn == null ? new String[0] : fqfn.split("/");
return parts.length >= 3 && !parts[0].isEmpty() && !parts[1].isEmpty() && !parts[2].isEmpty();
}
if (!validFqfn(input)) throw new IllegalArgumentException("Expected tenant/namespace/functionName, got: " + input); Type guard
static boolean isFqfn(String s) {
if (s == null) return false;
String[] p = s.split("/");
return p.length >= 3 && !p[0].isEmpty() && !p[1].isEmpty() && !p[2].isEmpty();
} Try / catch
try {
String tenant = FunctionCommon.extractTenantFromFullyQualifiedName(fqfn);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Invalid Fully Qualified Function Name")) {
throw new IllegalArgumentException("Pass tenant/namespace/functionName, got: " + fqfn);
}
throw e;
} Prevention
- Build FQFNs with FunctionCommon.getFullyQualifiedName(tenant, namespace, name) instead of string concatenation
- Distinguish function FQFNs from topic names in your config schema
- Validate user CLI input format before passing to extractors
- Keep a single helper for FQFN parsing to avoid format drift
When it happens
Trigger: Calling extractTenantFromFullyQualifiedName / extractNamespaceFromFullyQualifiedName / extractNameFromFullyQualifiedName with strings like 'my-function', 'tenant/namespace', an empty string, or a topic/subject name mistakenly passed instead of a function FQFN.
Common situations: Parsing user-provided CLI arguments where only the function name was given; passing a topic name (containing ':' or different separators) instead of a function name; passing a Pulsar topic or sink/source name that is tenant/namespace-only; legacy data written in a different format.
Related errors
- byte string cannot be empty
- Fully qualified function names (FQFNs) must be of the form t
- Either a Java jar or a Python file or a Go executable binary
- Either a Java jar or a Python file or a Go executable binary
- Function Name not provided
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/e5dff15bc1bb1f7d.
Report an issue: GitHub.