apache/iceberg · error · FunctionNotExistException
FunctionNotExistException
Error message
FunctionNotExistException
What it means
FlinkCatalog registers no functions, so getFunction always throws FunctionNotExistException for any function path. This mirrors the catalog contract: functionExists returns false and listFunctions returns empty. The exception signals the function namespace is entirely unimplemented for Iceberg catalogs.
Source
Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/FlinkCatalog.java:750
@Override
public void alterPartition(
ObjectPath tablePath,
CatalogPartitionSpec partitionSpec,
CatalogPartition newPartition,
boolean ignoreIfNotExists)
throws CatalogException {
throw new UnsupportedOperationException();
}
@Override
public List<String> listFunctions(String dbName) throws CatalogException {
return Collections.emptyList();
}
@Override
public CatalogFunction getFunction(ObjectPath functionPath)
throws FunctionNotExistException, CatalogException {
throw new FunctionNotExistException(getName(), functionPath);
}
@Override
public boolean functionExists(ObjectPath functionPath) throws CatalogException {
return false;
}
@Override
public void createFunction(
ObjectPath functionPath, CatalogFunction function, boolean ignoreIfExists)
throws CatalogException {
throw new UnsupportedOperationException();
}
@Override
public void alterFunction(
ObjectPath functionPath, CatalogFunction newFunction, boolean ignoreIfNotExists)
throws CatalogException {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use Flink's built-in functions or declare UDFs as temporary/system functions in the job (TableEnvironment.createTemporarySystemFunction) instead of catalog functions.
- If code may call getFunction, catch FunctionNotExistException and fall back to temporary function resolution.
- Register Iceberg transformations in SQL via temporary functions or views, not persistent catalog functions.
Example fix
// before
CatalogFunction f = catalog.getFunction(new ObjectPath(db, "my_udf"));
// after
try {
CatalogFunction f = catalog.getFunction(functionPath);
} catch (FunctionNotExistException e) {
tableEnv.createTemporarySystemFunction("my_udf", MyUdf.class);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (catalog instanceof FlinkCatalog) {
// no catalog functions exist; resolve UDFs via TableEnvironment instead
} Type guard
boolean supportsFunctions = !(catalog instanceof FlinkCatalog);
Try / catch
try {
fn = catalog.getFunction(functionPath);
} catch (FunctionNotExistException e) {
fn = tableEnv.getTemporarySystemFunction(functionPath.getObjectName())
.orElseThrow(() -> new IllegalStateException("Function not registered: " + functionPath.getObjectName()));
} Prevention
- Register UDFs as temporary/system functions in job bootstrap, never as catalog functions.
- Remember listFunctions/functionExists on FlinkCatalog always return empty/false.
When it happens
Trigger: Calling FlinkCatalog.getFunction(functionPath) for any function, or Flink SQL resolution of a catalog function (not a built-in/temporary function) in a session bound to FlinkCatalog.
Common situations: Registering UDFs through the catalog instead of the job; SQL scripts referencing persistent catalog functions after switching the catalog to Iceberg; tooling that enumerates catalog functions.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- DatabaseNotEmptyException
- Can not alter the default database when the iceberg catalog
- TableNotExistException
- Illegal table name:
- Namespaces are not supported by catalog:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/7acc896572d38422.
Report an issue: GitHub.