apache/shenyu · error · ShenyuTarsPluginException
ShenyuTarsPluginInitializeException: can't init prx with…
Error message
ShenyuTarsPluginInitializeException: can't init prx with empty ext string
What it means
ApplicationConfigCache.tryLockedLoadMetaData builds the TARS proxy class from MetaData. The rpcExt field (a JSON string describing the TARS servant methods) is mandatory — if it's empty, a ShenyuTarsPluginException is thrown because a proxy cannot be constructed without method information.
Solutions
- Fix the TARS client configuration so it registers metadata with a non-empty rpcExt (method/parameter description JSON), then re-register the service.
- Verify the shenyu-client version on the backend generates rpcExt for @ShenyuTarsClient endpoints.
- Correct the MetaData row in shenyu-admin (rpc_ext column) for the affected path, or delete it so the client re-registers.
- Check the registration/sync pipeline (admin logs) for metadata being truncated or dropped.
Defensive patterns
Strategy: validation
Validate before calling
MetaData md = metaDataService.findByPath(path);
if (md == null || md.getRpcExt() == null || md.getRpcExt().isEmpty()) {
throw new IllegalStateException("tars metadata for " + path + " has empty rpcExt; re-register the client");
} Try / catch
try {
initPrx(metaData);
} catch (ShenyuTarsPluginException e) {
LOG.error("tars proxy init failed for {}: {}", metaData.getPath(), e.getMessage());
} Prevention
- Ensure the backend TARS client registers rpcExt JSON with every @ShenyuTarsClient endpoint.
- Validate rpc_ext is non-empty in admin before publishing metadata to the gateway.
- After manual DB edits, re-register or re-sync metadata to restore rpcExt.
- Monitor admin registration logs for metadata records missing rpcExt.
When it happens
Trigger: A MetaData record for a tars service reaches tryLockedLoadMetaData (via initPrx on first invocation) with getRpcExt() returning null or empty string — i.e., the client registered metadata without the rpcExt payload.
Common situations: TARS backend client annotated/configured incorrectly so rpcExt wasn't populated during registration; metadata manually inserted into the admin DB without rpcExt; older client version not generating rpcExt; sync race where metadata arrives incomplete.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- client register param must config the appName or contextPath
- doRegister Failed to execute, because selectorDO object is…
- load extension resources error,subClass subtype is not of…
- load extension resources error,subClass without @Join…
- metaData exist under those namespace!
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/57e5d6f90601d271.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-tars/src/main/java/org/apache/shenyu/plugin/tars/cache/ApplicationConfigCache.java:223
}
}
/**
* Try to load once, if it fails, it will give up.<br>
* add class cache to {@link #prxClassCache}.<br>
* add method params cache to {@link #prxParamCache}.<br>
* add paths cache to {@link #ctxPathCache}.<br>
*
* @param metaData metaData
* @throws ClassNotFoundException meta data class definition not found
* @see ReentrantLock
*/
private void tryLockedLoadMetaData(final MetaData metaData) throws ClassNotFoundException {
Objects.requireNonNull(LOCK);
if (LOCK.tryLock()) {
try {
if (StringUtils.isEmpty(metaData.getRpcExt())) {
throw new ShenyuTarsPluginException("ShenyuTarsPluginInitializeException: can't init prx with empty ext string");
}
Class<?> prxClazz = buildClassDefinition(metaData);
prxClassCache.put(metaData.getPath(), prxClazz);
List<MetaData> paths = ctxPathCache.getOrDefault(metaData.getContextPath(), new ArrayList<>());
if (!IterableUtils.matchesAny(paths, p -> p.getPath().equals(metaData.getPath()))) {
paths.add(metaData);
}
ctxPathCache.put(metaData.getContextPath(), paths);
} finally {
LOCK.unlock();
}
}
}
/**
* build target class definition.
*
* @param metaData metadataView on GitHub (pinned to 567142e072)