apache/shenyu · error · IllegalArgumentException
is malformed
Error message
is malformed
What it means
ShenyuClientsRegistrar.getUrl() resolves the @ShenyuClient url attribute (possibly from a property placeholder), strips any trailing slash, and validates it with java.net.URL. If the resolved string is not a well-formed URL, it throws IllegalArgumentException wrapping the MalformedURLException. This fails fast at bean-registration time instead of letting the client fail on its first request.
Solutions
- Add the scheme prefix, e.g. change url = "localhost:9195" to url = "http://localhost:9195".
- Ensure the property referenced by ${...} exists in the environment (application.yml, env var) so the placeholder resolves.
- Print/log the resolved value and fix the exact malformed segment reported in the message (it is prefixed to the error).
- If the target is not a full URL, use the configured serverList/registerType=local discovery path instead of a static url.
Example fix
// before
@ShenyuClient(name = "order", url = "${shenyu.gateway}") // shenyu.gateway=localhost:9195
// after
@ShenyuClient(name = "order", url = "${shenyu.gateway}") // shenyu.gateway=http://localhost:9195 Defensive patterns
Strategy: validation
Validate before calling
String url = env.resolvePlaceholders(clientUrl);
if (url == null || url.isBlank() || !url.matches("^https?://[^\s]+")) {
throw new IllegalArgumentException("@ShenyuClient url must be a full http(s) URL, got: " + url);
} Prevention
- Always use fully-qualified http(s) URLs in @ShenyuClient url attributes.
- Keep gateway URLs in application.yml so placeholders resolve in one place.
- Add a startup test that resolves and validates every client URL.
When it happens
Trigger: Registering a @ShenyuClient (feign SDK) whose url attribute resolves, after placeholder substitution, to a string java.net.URL cannot parse — e.g. "localhost:8080" (no scheme), "http//host", "${gateway.url}" left unresolved, or an empty/whitespace value.
Common situations: Typo in the url scheme in application.yml; referencing a property that does not exist so the raw placeholder string is passed through; forgetting the http:// prefix; copying a URL with stray characters from docs.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- is malformed
- shenyu.jwt.secretKey is not configured. In a multi-instance…
- clientConfig must config " + getClientName() + " properties
- grpc client must config the contextPath, ipAndPort
- zookeeper url is empty
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/4e05af9adde2c36e.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-sdk/shenyu-sdk-feign/src/main/java/org/apache/shenyu/sdk/feign/ShenyuClientsRegistrar.java:409
/**
* Gets url.
* @param url the url
* @return the url
*/
static String getUrl(final String url) {
String resultUrl = url;
if (StringUtils.hasText(resultUrl) && !(resultUrl.startsWith("#{") && resultUrl.contains("}"))) {
if (!resultUrl.contains("://")) {
resultUrl = "http://" + resultUrl;
}
if (resultUrl.endsWith("/")) {
resultUrl = resultUrl.substring(0, resultUrl.length() - 1);
}
try {
new URL(resultUrl);
} catch (MalformedURLException e) {
throw new IllegalArgumentException(resultUrl + " is malformed", e);
}
}
return resultUrl;
}
private String getUrl(final ConfigurableBeanFactory beanFactory, final Map<String, Object> attributes) {
String url = resolve(beanFactory, (String) attributes.get("url"));
return getUrl(url);
}
private String getPath(final ConfigurableBeanFactory beanFactory, final Map<String, Object> attributes) {
String path = resolve(beanFactory, (String) attributes.get("path"));
return getPath(path);
}
/**
* Gets path.
* @param path the pathView on GitHub (pinned to 567142e072)