apache/pulsar · error · IllegalStateException
The function registration references a different set of jar
Error message
The function registration references a different set of jar files than previous registrations for this function : old = ${jarFiles}, new = ${requiredJarFiles} What it means
FunctionCacheEntry.register() enforces that every registration of the same function (same function ID/entry) uses exactly the same set of jar files as previously registered instances. This IllegalStateException is thrown when the requiredJarFiles passed in differ from the jarFiles already recorded (different size or different contents), indicating inconsistent function metadata across instances of the same function.
Source
Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/functioncache/FunctionCacheEntry.java:90
.narFile(new File(narArchive))
.extractionDirectory(narExtractionDirectory)
.parentClassLoader(rootClassLoader)
.build();
this.classpaths = Collections.emptySet();
this.jarFiles = Collections.singleton(narArchive);
this.executionHolders = new HashSet<>(Collections.singleton(initialInstanceId));
}
boolean isInstanceRegistered(String iid) {
return executionHolders.contains(iid);
}
public void register(String eid,
Collection<String> requiredJarFiles,
Collection<URL> requiredClassPaths) {
if (jarFiles.size() != requiredJarFiles.size()
|| !new HashSet<>(requiredJarFiles).containsAll(jarFiles)) {
throw new IllegalStateException(
"The function registration references a different set of jar files than "
+ " previous registrations for this function : old = " + jarFiles
+ ", new = " + requiredJarFiles);
}
if (classpaths.size() != requiredClassPaths.size()
|| !requiredClassPaths.stream().map(URL::toString).collect(Collectors.toSet())
.containsAll(classpaths)) {
throw new IllegalStateException(
"The function registration references a different set of classpaths than "
+ " previous registrations for this function : old = " + classpaths
+ ", new = " + requiredClassPaths);
}
this.executionHolders.add(eid);
}
public boolean unregister(String eid) {View on GitHub (pinned to 820761864e)
Solutions
- Delete/unregister all existing instances for this function (FunctionCacheManagerImpl.removeFunction) so a fresh FunctionCacheEntry is created, then register with the new jar set.
- Ensure every instance of the same function uses the identical jar file paths (same downloaded archive location).
- If the function was updated, trigger a full restart of the function instances so the cache entry is recreated.
Example fix
// before: re-registering an updated jar against the same entry CacheEntry cache = cacheManager.getFunctionCacheEntry(tenant, namespace, name); cache.register(eid, newJars, classpaths); // IllegalStateException: different set of jar files // after cacheManager.removeFunction(tenant, namespace, name); cacheManager.getFunctionCacheEntry(tenant, namespace, name, ...).register(eid, newJars, classpaths);
Defensive patterns
Strategy: try-catch
Validate before calling
FunctionCacheEntry existing = cacheManager.getFunctionCacheEntry(tenant, namespace, name);
if (existing != null && !existingJarPaths.equals(requiredJarFiles)) {
cacheManager.removeFunction(tenant, namespace, name); // rebuild entry with the new jar set
} Try / catch
try {
entry.register(eid, requiredJarFiles, requiredClassPaths);
} catch (IllegalStateException e) {
if (e.getMessage().contains("different set of jar files")) {
cacheManager.removeFunction(tenant, namespace, name);
// recreate entry and register again
} else {
throw e;
}
} Prevention
- Always restart function instances after changing the function package so the cache entry is rebuilt.
- Use a deterministic, single download location per function package so all instances register identical jar paths.
- Compare the current registered jar set before re-registering an updated function.
When it happens
Trigger: Calling register(eid, requiredJarFiles, requiredClassPaths) on an existing FunctionCacheEntry (via registerFunctionInstance / registerFunctionInstanceWithArchive in FunctionCacheManagerImpl) where requiredJarFiles is not equal to the set recorded from earlier registrations — e.g. a jar path changed, was added, or removed for a second instance of the same function.
Common situations: Updating a function's jar while old instances are still registered (restart with new package location/version); different worker instances resolving the function package to different paths (local vs distributed download dir); a function update that changed the archive while the cache entry was reused; mixing NAR and non-NAR package locations.
Related errors
- The function registration references a different set of clas
- No dependencies are registered for function ${fid}
- State key needs to be specified
- Source does not implement correct interface
- Sink does not implement correct interface
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/fe1f4f1ffd491a4c.
Report an issue: GitHub.