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

  1. Ensure the string has the form tenant/namespace/functionName before calling the extractors
  2. Build the FQFN from components with FunctionCommon.getFullyQualifiedName(tenant, namespace, name) when you only have parts
  3. Add a precondition check (split('/') >= 3) in your calling code and produce a clearer error message
  4. 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

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


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/e5dff15bc1bb1f7d. Report an issue: GitHub.