grpc/grpc-java · error · IllegalArgumentException
StringMatcher (match_pattern) must be non-empty
Error message
StringMatcher (match_pattern) must be non-empty
What it means
checkNonEmpty rejects StringMatcher values that are empty (e.g. an empty contains or exact value) with an IllegalArgumentException of the form 'StringMatcher <name> (match_pattern) must be non-empty'. The parser treats an empty match value as invalid config because it would match nothing meaningful.
Solutions
- Populate the match value with a non-empty string in the xDS config
- Reject empty match values at the management server before distribution
- Check for templating/config-generation bugs that emit empty values
- If an empty match is intentional, use a different pattern type (e.g. prefix) if semantics allow
Example fix
// before
{"string_match":{"contains":""}}
// after
{"string_match":{"contains":"session="}} Defensive patterns
Strategy: validation
Validate before calling
if (value == null || value.isEmpty()) { reject(name + " must be non-empty"); } Type guard
null
Try / catch
try { matcher = MatcherParser.parseHeaderMatcher(proto); }
catch (IllegalArgumentException e) { if (e.getMessage().contains("must be non-empty")) { fixConfigEntry(); } } Prevention
- Never emit empty match values from config tooling
- Fill template placeholders; fail generation on empty values
- Validate config fields server-side
When it happens
Trigger: parseStringMatcher calls checkNonEmpty (e.g. for contains) and the proto field is set but holds an empty string.
Common situations: contains:"" or exact:"" in Envoy config generated by tooling; a field defaulting to empty after stripping whitespace; templating bug leaving a placeholder unfilled.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- HeaderMatcher [] contains malformed safe regex pattern:
- Unknown header matcher type:
- Unknown StringMatcher match pattern:
- Invalid address: Empty address is not allowed.
- Invalid allowed_grpc_services config for
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/0de378836f99a4f9.
Report an issue: GitHub.
Appendix: source
Thrown at xds/src/main/java/io/grpc/xds/internal/MatcherParser.java:139
case SUFFIX:
return Matchers.StringMatcher.forSuffix(
checkNonEmpty(proto.getSuffix(), "suffix"), proto.getIgnoreCase());
case SAFE_REGEX:
String regex = checkNonEmpty(proto.getSafeRegex().getRegex(), "regex");
return Matchers.StringMatcher.forSafeRegEx(Pattern.compile(regex));
case CONTAINS:
return Matchers.StringMatcher.forContains(
checkNonEmpty(proto.getContains(), "contains"), proto.getIgnoreCase());
case MATCHPATTERN_NOT_SET:
default:
throw new IllegalArgumentException(
"Unknown StringMatcher match pattern: " + proto.getMatchPatternCase());
}
}
private static String checkNonEmpty(String value, String name) {
if (value.isEmpty()) {
throw new IllegalArgumentException("StringMatcher " + name
+ " (match_pattern) must be non-empty");
}
return value;
}
/** Translates envoy proto FractionalPercent to internal FractionMatcher. */
public static Matchers.FractionMatcher parseFractionMatcher(
io.envoyproxy.envoy.type.v3.FractionalPercent proto) {
int denominator;
switch (proto.getDenominator()) {
case HUNDRED:
denominator = 100;
break;
case TEN_THOUSAND:
denominator = 10_000;
break;
case MILLION:
denominator = 1_000_000;View on GitHub (pinned to 64daddc1f3)