alibaba/nacos · warning · TimeoutException

fuzzy watch result future timeout for {unit.toMillis(timeout

Error message

fuzzy watch result future timeout for {unit.toMillis(timeout)} millis

What it means

Thrown as TimeoutException by the Future returned from ConfigFuzzyWatchContext.createNewFuture().get(timeout, unit) when initializationCompleted is still false after waiting unit.toMillis(timeout). The context waits on its intrinsic monitor for the server to finish the initial fuzzy-watch sync; if it does not complete in time, the bounded get throws.

Source

Thrown at client/src/main/java/com/alibaba/nacos/client/config/impl/ConfigFuzzyWatchContext.java:547

            public Set<String> get() throws InterruptedException, ExecutionException {
                synchronized (ConfigFuzzyWatchContext.this) {
                    while (!ConfigFuzzyWatchContext.this.initializationCompleted.get()) {
                        ConfigFuzzyWatchContext.this.wait();
                    }
                }
                return new HashSet<>(ConfigFuzzyWatchContext.this.getReceivedGroupKeys());
            }
            
            public Set<String> get(long timeout, TimeUnit unit)
                throws InterruptedException, TimeoutException {
                if (!ConfigFuzzyWatchContext.this.initializationCompleted.get()) {
                    synchronized (ConfigFuzzyWatchContext.this) {
                        ConfigFuzzyWatchContext.this.wait(unit.toMillis(timeout));
                    }
                }
                
                if (!ConfigFuzzyWatchContext.this.initializationCompleted.get()) {
                    throw new TimeoutException(
                        "fuzzy watch result future timeout for " + unit.toMillis(timeout)
                            + " millis");
                }
                return new HashSet<>(ConfigFuzzyWatchContext.this.getReceivedGroupKeys());
            }
        };
        
        return future;
    }
}

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Increase the timeout passed to get() to match the expected sync duration.
  2. Reduce the dataId/group pattern breadth so fewer configs match and sync faster.
  3. Verify the server is healthy and the gRPC connection is stable so the init handshake completes.
  4. If acceptable, use the no-timeout get() that blocks until completion.

Example fix

// before
Set<String> keys = future.get(2, TimeUnit.SECONDS);

// after
Set<String> keys = future.get(30, TimeUnit.SECONDS);
Defensive patterns

Strategy: try-catch

Validate before calling

// size the timeout to the expected sync duration for the matched set size
long timeoutMs = Math.max(5_000, matchedKeyEstimate * 50L);

Try / catch

try {
    Set<String> keys = future.get(30, TimeUnit.SECONDS);
} catch (TimeoutException te) {
    log.warn("fuzzy watch init not complete in time; retry or widen pattern");
}

Prevention

When it happens

Trigger: Calling future.get(N, unit) on a fuzzy-watch future whose server-side initialization has not finished within N (e.g. server slow, many matched configs, or connection issue delaying the sync).

Common situations: Large config namespace matching many keys (slow initial sync), server under load, network delay, or too-short a timeout relative to the matched set size.

Understand the failure class

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/527894073af7466f. Report an issue: GitHub.