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

  1. Trim the condition value before storing/calling validate: value.trim().
  2. Remove any internal spaces from the URI path; URIs cannot contain raw whitespace.
  3. URL-encode any legitimately special segment instead of embedding spaces.
  4. 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

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


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)