apache/pulsar · error · IllegalStateException

The function registration references a different set of clas

Error message

The function registration references a different set of classpaths than  previous registrations for this function : old = ${classpaths}, new = ${requiredClassPaths}

What it means

FunctionCacheEntry.register() also verifies that the extra classpath URLs (requiredClassPaths) match those recorded from prior registrations for the same function entry. This IllegalStateException is thrown when the set of classpath URLs differs (in size or contents) from previously registered classpaths — the same function must present a consistent classpath across all its instances.

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/functioncache/FunctionCacheEntry.java:99

    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) {
        this.executionHolders.remove(eid);
        return this.executionHolders.isEmpty();
    }

    @Override
    public void close() {
        try {
            classLoader.close();
        } catch (IOException e) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Remove the function's cache entry (removeFunction) and re-register fresh with the new classpath set.
  2. Ensure identical, canonical URL strings (same scheme/path) are produced for every instance registration.
  3. Restart all function instances after a dependency change so the entry is rebuilt.

Example fix

// before
cache.register(eid, jars, Arrays.asList(new URL("file:/extra-dep.jar"))); // old entry had different URLs
// after
cacheManager.removeFunction(tenant, namespace, name);
var freshEntry = cacheManager.getFunctionCacheEntry(tenant, namespace, name, null, null, null, null, null, null, false, null);
freshEntry.register(eid, jars, Arrays.asList(new URL("file:/extra-dep.jar")));
Defensive patterns

Strategy: try-catch

Validate before calling

FunctionCacheEntry existing = cacheManager.getFunctionCacheEntry(tenant, namespace, name);
if (existing != null && !existingClasspathStrings.equals(requiredClassPaths.stream().map(URL::toString).collect(Collectors.toSet()))) {
    cacheManager.removeFunction(tenant, namespace, name);
}

Try / catch

try {
    entry.register(eid, requiredJarFiles, requiredClassPaths);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("different set of classpaths")) {
        cacheManager.removeFunction(tenant, namespace, name);
        // recreate entry and register again
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling register(eid, requiredJarFiles, requiredClassPaths) on a FunctionCacheEntry that already holds classpaths, where the new URL set is not equal to the old set (URLs compared by string form).

Common situations: A function update adding/removing extra classpath dependencies while old instances remain; URL string differences (file:// vs path form, trailing slash, host differences) causing set inequality despite the same file; different workers computing different classpath URLs for the same function.

Related errors


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