apache/skywalking · error · IllegalArgumentException

Duplicate MAL extension namespace '{}' from {}

Error message

Duplicate MAL extension namespace '{}' from {}

What it means

SPI validation error from MalExtensionRegistry: two different MalFunctionExtension implementations report the same namespace via name(), and both export at least one @MALContextFunction method. Method names only need to be unique within a namespace, so a duplicate namespace would create ambiguity in ns::method resolution and in generated static calls — the second registration throws.

Source

Thrown at oap-server/analyzer/meter-analyzer/src/main/java/org/apache/skywalking/oap/meter/analyzer/v2/compiler/rt/MalExtensionRegistry.java:129

                    }
                }
            }
            final String methodName = m.getName();
            if (methods.containsKey(methodName)) {
                throw new IllegalArgumentException(
                    "Duplicate @MALContextFunction name '" + methodName
                        + "' in namespace '" + namespace
                        + "' from " + ext.getClass().getName());
            }
            final String fqcn = m.getDeclaringClass().getName();
            methods.put(methodName,
                        new ExtensionMethod(fqcn, methodName, extraParamTypes));
            log.info("Registered MAL extension function {}::{}() -> {}.{}()",
                     namespace, methodName, fqcn, methodName);
        }
        if (!methods.isEmpty()) {
            if (REGISTRY.containsKey(namespace)) {
                throw new IllegalArgumentException(
                    "Duplicate MAL extension namespace '" + namespace
                        + "' from " + ext.getClass().getName());
            }
            REGISTRY.put(namespace, methods);
        }
    }

    /**
     * Look up an extension method at compile time for validation and codegen.
     *
     * @return the extension method descriptor, or null if not found
     */
    public static ExtensionMethod lookup(final String namespace,
                                          final String methodName) {
        final Map<String, ExtensionMethod> methods = REGISTRY.get(namespace);
        if (methods == null) {
            return null;
        }

View on GitHub (pinned to 102af09b4a)

Solutions

  1. Ensure only one jar providing a given namespace is on the classpath — remove old versions from ext/ or oap-libs
  2. If both must coexist, rename one implementation's name() namespace and update rules accordingly
  3. Check for duplicate SPI entries across jars: grep the META-INF/services files of all deployed extension jars

Example fix

# before: two jars both declare
public String name() { return "genai"; }

# after: remove the stale jar, or rename one
public String name() { return "genai2"; }  # and update rules to genai2::...
Defensive patterns

Strategy: validation

Validate before calling

// deployment check: ensure no two jars declare the same namespace
Set<String> namespaces = new HashSet<>();
for (MalFunctionExtension e : ServiceLoader.load(MalFunctionExtension.class)) {
    if (!namespaces.add(e.name())) {
        throw new IllegalStateException("Duplicate MAL extension namespace: " + e.name());
    }
}

Try / catch

startup-time; remove the duplicate jar from the classpath (ext/, oap-libs) rather than catching

Prevention

When it happens

Trigger: Two jars each contain a class implementing MalFunctionExtension with name() returning e.g. "genai" and both have annotated methods; REGISTRY.containsKey(namespace) is true when the second one finishes scanning its methods.

Common situations: Deploying two versions of a custom extension jar into OAP's oap-libs/ext simultaneously; a fork and the original of the same extension both on the classpath; copy-pasting an extension class without changing name().

Related errors


AI-assisted analysis of apache/skywalking@102af09b4a (2026-08-14). Data as JSON: /api/errors/b25f17b39f9ef8b6. Report an issue: GitHub.