apache/shenyu · error · IllegalArgumentException
Only HTTP and HTTPS protocols are allowed
Error message
Only HTTP and HTTPS protocols are allowed
What it means
As part of SSRF protection, validateUrlForSSRF restricts the parsed URL's scheme to HTTP or HTTPS and throws IllegalArgumentException "Only HTTP and HTTPS protocols are allowed" for anything else. This blocks file://, ftp://, gopher://, data:, etc., which are common SSRF exploitation vectors.
Solutions
- Use only http:// or https:// URLs for targets admin fetches.
- Move files to a location served over HTTP(S) if the intent was to fetch local content via URL.
- Do not bypass the validation; if another protocol is genuinely needed, use a dedicated, reviewed code path instead of the SSRF-guarded HTTP client.
- Catch IllegalArgumentException and log the rejected scheme for security auditing.
Example fix
// before
validateUrlForSSRF("file:///etc/shenyu/config.yaml");
// after
validateUrlForSSRF("https://backend.example.com/config"); Defensive patterns
Strategy: validation
Validate before calling
HttpUrl parsed = HttpUrl.parse(url);
String scheme = parsed != null ? parsed.scheme() : null;
if (!"http".equals(scheme) && !"https".equals(scheme)) {
throw new IllegalArgumentException("Only http/https targets are supported: " + scheme);
} Type guard
boolean isHttpScheme(String s) {
HttpUrl u = s == null ? null : HttpUrl.parse(s.trim());
return u != null && ("http".equals(u.scheme()) || "https".equals(u.scheme()));
} Try / catch
try {
UrlSecurityUtils.validateUrlForSSRF(url);
} catch (IllegalArgumentException e) {
log.warn("Blocked non-HTTP(S) target (possible SSRF attempt): {}", url);
return ResponseEntity.badRequest().body("Only http and https URLs are allowed");
} Prevention
- Treat attempts to submit file://, gopher://, ftp:// URLs as suspicious and log them.
- Restrict UI inputs to http/https URL pickers/validators.
- Never fetch arbitrary user-supplied URLs outside the SSRF-validated path.
- Keep the validation in place — do not special-case non-HTTP protocols.
When it happens
Trigger: Calling validateUrlForSSRF with URLs like 'file:///etc/passwd', 'ftp://host/file', 'gopher://...', or 'jdbc:...' — any scheme other than http/https.
Common situations: Attack payloads attempting to read local files or reach internal services via alternative protocols; misconfiguration where a user pastes a non-HTTP service URL (e.g. an FTP download) into a webhook/health-check field.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- URL cannot be empty
- Invalid URL format
- Access to localhost is not allowed
- Host cannot be empty
- Access to private or internal IP addresses is not allowed
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/03aff5105b30113a.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/utils/UrlSecurityUtils.java:64
*
* @param url the URL to validate
* @throws IllegalArgumentException if the URL is not safe for external requests
*/
public static void validateUrlForSSRF(final String url) {
if (Objects.isNull(url) || url.trim().isEmpty()) {
throw new IllegalArgumentException("URL cannot be empty");
}
HttpUrl parsedUrl = HttpUrl.parse(url);
if (Objects.isNull(parsedUrl)) {
throw new IllegalArgumentException("Invalid URL format");
}
String protocol = parsedUrl.scheme();
// Only allow HTTP and HTTPS protocols
if (!HTTP_PROTOCOL.equals(protocol) && !HTTPS_PROTOCOL.equals(protocol)) {
throw new IllegalArgumentException("Only HTTP and HTTPS protocols are allowed");
}
// Validate host for SSRF protection using the same URL parser as request execution.
validateHostForSSRF(parsedUrl.host(), parsedUrl.port());
}
/**
* Validate host to prevent SSRF attacks.
*
* @param host the host to validate
* @param port the port to validate
* @throws IllegalArgumentException if the host is not allowed
*/
public static void validateHostForSSRF(final String host, final int port) {
if (Objects.isNull(host) || host.trim().isEmpty()) {
throw new IllegalArgumentException("Host cannot be empty");
}
View on GitHub (pinned to 567142e072)