apache/shenyu · error · IllegalArgumentException
The URI cannot contain whitespaces. Current value: " + value
Error message
The URI cannot contain whitespaces. Current value: " + value
What it means
UriConditionValidator validates the value of a URI-based selector condition before it is parsed by the matching operator (EQ, CONTAINS, etc.). It rejects values that contain whitespace characters (space, tab, newline) because such values could never match a URI path and would silently produce broken condition matching. The check runs eagerly in the static VALIDATOR_MAP consumers when validate() is invoked.
Solutions
- Trim the condition value before storing/calling validate: value.trim().
- Remove any internal spaces from the URI path; URIs cannot contain raw whitespace.
- URL-encode any legitimately special segment instead of embedding spaces.
- Check for newline contamination from file/config reads (strip \r\n).
Example fix
// before
UriConditionValidator.validate("eq", "/api/ order");
// after
UriConditionValidator.validate("eq", "/api/order"); // trimmed, no whitespace Defensive patterns
Strategy: validation
Validate before calling
if (value != null && value.matches(".*[ \\t\\n\\r].*")) { throw new IllegalArgumentException("URI condition value must not contain whitespace: " + value); } Type guard
boolean isValidUriCondition(String v) { return v != null && v.startsWith("/") && !v.matches(".*[ \\t\\n\\r].*"); } Try / catch
try { UriConditionValidator.validate(operator, value); } catch (IllegalArgumentException e) { log.warn("Invalid URI condition value: {}", value); /* reject or trim */ } Prevention
- Always trim values read from the dashboard/API before validating.
- Reject whitespace in condition value fields at the UI level.
- Strip trailing newlines when importing conditions from files.
- Treat URI paths as encoded strings; never embed raw spaces.
When it happens
Trigger: Calling UriConditionValidator.validate(operator, value) with an operator alias mapped to commonPathValidator (EQ, CONTAINS, STARTS_WITH-family routed there) and a value containing a space, tab, or newline — e.g. value "/api/ hello" or one pasted with a trailing newline.
Common situations: Copying a URI from documentation or a browser with trailing whitespace, hand-editing selector conditions in the dashboard with a stray space, or programmatically building conditions by concatenating strings without trimming.
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
- The URI must start with '/'
- The URI must be blank
- The URI condition value cannot be empty.
- namespaceId is null
- namespaceId is not exist
AI-assisted analysis of apache/shenyu@567142e072 (2026-09-12).
Data as JSON: /api/errors/3e754b61444ae7bf.
Report an issue: GitHub.
Appendix: source
Thrown at shenyu-admin/src/main/java/org/apache/shenyu/admin/validation/validator/UriConditionValidator.java:40
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);
VALIDATOR_MAP.put(OperatorEnum.EXCLUDE.getAlias(), commonPathValidator);
VALIDATOR_MAP.put(OperatorEnum.CONTAINS.getAlias(), commonPathValidator);
VALIDATOR_MAP.put(OperatorEnum.IS_BLANK.getAlias(), blankPathValidator);View on GitHub (pinned to 567142e072)