alibaba/Sentinel · error · IllegalArgumentException

Bad argument: serverAddr=[%s], path=[%s]

Error message

Bad argument: serverAddr=[%s], path=[%s]

What it means

Thrown by the ZookeeperDataSource path-style constructor when serverAddr or path is blank. The constructor subscribes to a single ZooKeeper znode whose full path you supply; blank values make the watch meaningless, so Sentinel rejects them before connecting.

Source

Thrown at sentinel-extension/sentinel-datasource-zookeeper/src/main/java/com/alibaba/csp/sentinel/datasource/zookeeper/ZookeeperDataSource.java:52

    private static volatile Map<String, CuratorFramework> zkClientMap = new HashMap<>();
    private static final Object lock = new Object();


    private final ExecutorService pool = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<Runnable>(1), new NamedThreadFactory("sentinel-zookeeper-ds-update", true),
            new ThreadPoolExecutor.DiscardOldestPolicy());

    private CuratorCacheListener listener;
    private final String path;

    private CuratorFramework zkClient = null;
    private CuratorCache nodeCache = null;

    public ZookeeperDataSource(final String serverAddr, final String path, Converter<String, T> parser) {
        super(parser);
        if (StringUtil.isBlank(serverAddr) || StringUtil.isBlank(path)) {
            throw new IllegalArgumentException(String.format("Bad argument: serverAddr=[%s], path=[%s]", serverAddr, path));
        }
        this.path = path;

        init(serverAddr, null);
    }

    /**
     * This constructor is Nacos-style.
     */
    public ZookeeperDataSource(final String serverAddr, final String groupId, final String dataId,
                               Converter<String, T> parser) {
        super(parser);
        if (StringUtil.isBlank(serverAddr) || StringUtil.isBlank(groupId) || StringUtil.isBlank(dataId)) {
            throw new IllegalArgumentException(String.format("Bad argument: serverAddr=[%s], groupId=[%s], dataId=[%s]", serverAddr, groupId, dataId));
        }
        this.path = getPath(groupId, dataId);

        init(serverAddr, null);

View on GitHub (pinned to a3f40ba8e9)

Solutions

  1. Set a valid address like "127.0.0.1:2181" and a real znode path like "/sentinel/rules/my-app".
  2. Verify the znode exists in ZooKeeper (zkCli.sh: ls /sentinel/rules/my-app) so the watch has something to observe.
  3. Validate both values from your config before construction and fail with the offending property name.

Example fix

// before
new ZookeeperDataSource<>(null, "/sentinel/rules", parser);

// after
new ZookeeperDataSource<>("zk.prod:2181", "/sentinel/rules/my-app", parser);
Defensive patterns

Strategy: validation

Validate before calling

if (StringUtil.isBlank(serverAddr) || StringUtil.isBlank(path)) {
    throw new IllegalArgumentException("zookeeper serverAddr and znode path are required, got: "
        + serverAddr + ", " + path);
}
new ZookeeperDataSource<>(serverAddr, path, parser);

Try / catch

try {
    new ZookeeperDataSource<>(serverAddr, path, parser);
} catch (IllegalArgumentException e) {
    throw new IllegalStateException("ZooKeeper datasource misconfigured: addr=" + serverAddr + " path=" + path, e);
}

Prevention

When it happens

Trigger: new ZookeeperDataSource(serverAddr, path, parser) with a null/empty serverAddr (e.g. unresolved "${zk.addr}" placeholder) or a missing/blank znode path (no leading /zk path to the config node).

Common situations: ZooKeeper address property missing in one environment; path key typo so lookup returns null; copy-pasted example with placeholder strings never replaced.

Related errors


AI-assisted analysis of alibaba/Sentinel@a3f40ba8e9 (2026-08-14). Data as JSON: /api/errors/116361c48bbd9355. Report an issue: GitHub.