apache/dubbo · error · IllegalArgumentException

interface limit exceeded

Error message

interface limit exceeded

What it means

Thrown by Proxy.getProxy when the number of interfaces passed exceeds MAX_PROXY_COUNT (65535). It is a sanity cap: a generated proxy with that many interfaces would be pathological and almost always indicates a caller bug that built a huge array.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/bytecode/Proxy.java:65

    private static final AtomicLong PROXY_CLASS_COUNTER = new AtomicLong(0);
    private static final Map<ClassLoader, Map<String, Proxy>> PROXY_CACHE_MAP = new WeakHashMap<>();

    private final Class<?> classToCreate;

    protected Proxy(Class<?> classToCreate) {
        this.classToCreate = classToCreate;
    }

    /**
     * Get proxy.
     *
     * @param ics interface class array.
     * @return Proxy instance.
     */
    public static Proxy getProxy(Class<?>... ics) {
        if (ics.length > MAX_PROXY_COUNT) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

        // ClassLoader from App Interface should support load some class from Dubbo
        ClassLoader cl = ics[0].getClassLoader();
        ProtectionDomain domain = ics[0].getProtectionDomain();

        // use interface class name list as key.
        String key = buildInterfacesKey(cl, ics);

        // get cache by class loader.
        final Map<String, Proxy> cache;
        synchronized (PROXY_CACHE_MAP) {
            cache = PROXY_CACHE_MAP.computeIfAbsent(cl, k -> new ConcurrentHashMap<>());
        }

        Proxy proxy = cache.get(key);
        if (proxy == null) {
            synchronized (ics[0]) {

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Check how the ics array is built; deduplicate and keep only the interfaces you actually need to proxy.
  2. If you genuinely need many interfaces, split into several proxies.
  3. Add an assertion logging ics.length before calling getProxy to catch runaway arrays.

Example fix

// before
Class<?>[] all = collectEveryInterface(classpath); // thousands
Proxy.getProxy(all);

// after
Set<Class<?>> needed = new HashSet<>(Arrays.asList(ServiceA.class, ServiceB.class));
Proxy.getProxy(needed.toArray(new Class<?>[0]));
Defensive patterns

Strategy: validation

Validate before calling

if (ics.length > 65535) {
    throw new IllegalArgumentException("too many interfaces: " + ics.length);
}
Proxy.getProxy(ics);

Prevention

When it happens

Trigger: Proxy.getProxy(ics) with ics.length > 65535, e.g. accidentally passing every loaded interface or a collection flattened into a Class<?> array.

Common situations: A loop that accumulates interfaces without dedup; passing Class.getInterfaces() of many classes merged together; a reflective scan that gathered transitive interfaces; essentially always a programming bug, never a realistic workload.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/2db3e2bb6b0e0ff6. Report an issue: GitHub.