apache/shenyu · error · IllegalArgumentException
The URI must start with '/'
Error message
The URI must start with '/'
What it means
UriConditionValidator validates URI-type condition parameter values on selector/rule conditions in shenyu-admin. Its commonPathValidator requires every URI value to start with '/' and throws IllegalArgumentException otherwise. This ensures condition values are valid path expressions for gateway matching.
Solutions
- Prefix the value with '/': use "/api/user", not "api/user".
- Strip scheme/host if a full URL was pasted — keep only the path portion.
- Update automation/scripts to normalize path values before calling the admin API.
Example fix
// before
condition.setParamValue("api/user");
// after
condition.setParamValue("/api/user"); Defensive patterns
Strategy: validation
Validate before calling
String normalizeUri(String value) {
if (value.startsWith("http://") || value.startsWith("https://")) {
value = URI.create(value).getPath();
}
if (!value.startsWith("/")) { value = "/" + value; }
return value;
} Type guard
boolean isValidUriCondition(String value) {
return value != null && value.startsWith("/") && !value.matches(".*[ \\t\\n].*");
} Try / catch
try {
conditionService.save(condition);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("must start with '/'")) {
log.error("Fix condition URI: prefix value with '/'");
}
} Prevention
- Always express URI conditions as paths starting with '/'.
- Strip scheme and host when pasting full URLs into condition editors.
- Normalize path values in automation before calling the admin API.
When it happens
Trigger: Saving a selector or rule with a URI condition whose value does not begin with '/', e.g. "api/user" or "http://host/api" instead of "/api/user"; the validator's static VALIDATOR_MAP consumer runs on the stored value.
Common situations: Typing relative or full-URL values into the dashboard's condition editor; scripted admin API calls that build condition values without the leading slash; copy-pasting backend URLs into path conditions.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- parameter error
- WebI18nException(message, objects)
- The URI cannot contain whitespaces. Current value: " + value
- The URI must be blank
- The URI condition value cannot be empty.
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/5ec26b0f3033844c.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/validation/validator/UriConditionValidator.java:37
import com.google.re2j.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.apache.shenyu.common.enums.OperatorEnum;
import org.springframework.web.util.pattern.PathPatternParser;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
public class UriConditionValidator {
private static final Map<String, Consumer<String>> VALIDATOR_MAP = new HashMap<>();
static {
Consumer<String> commonPathValidator = value -> {
if (!value.startsWith("/")) {
throw new IllegalArgumentException("The URI must start with '/'");
}
if (StringUtils.containsAny(value, " ", "\t", "\n")) {
throw new IllegalArgumentException(
"The URI cannot contain whitespaces. Current value: " + value);
}
};
Consumer<String> blankPathValidator = value -> {
if (StringUtils.isNotBlank(value)) {
throw new IllegalArgumentException("The URI must be blank");
}
};
VALIDATOR_MAP.put(OperatorEnum.PATH_PATTERN.getAlias(),
PathPatternParser.defaultInstance::parse);
VALIDATOR_MAP.put(OperatorEnum.REGEX.getAlias(), Pattern::compile);
VALIDATOR_MAP.put(OperatorEnum.EQ.getAlias(), commonPathValidator);
VALIDATOR_MAP.put(OperatorEnum.STARTS_WITH.getAlias(), commonPathValidator);
VALIDATOR_MAP.put(OperatorEnum.ENDS_WITH.getAlias(), commonPathValidator);
VALIDATOR_MAP.put(OperatorEnum.MATCH.getAlias(), commonPathValidator);View on GitHub (pinned to 567142e072)