grpc/grpc-java · error · IllegalArgumentException
Invalid character in scheme at index ${i}
Error message
Invalid character in scheme at index ${i} What it means
Thrown by Uri.Builder's scheme setters when the scheme string contains a character outside the legal scheme alphabet (letters, digits, +, -, .). The first character must be alphabetic (checked separately) and every subsequent character must pass the schemeChars BitSet. This enforces RFC 3986 scheme syntax so the parsed URI is well-formed.
Source
Thrown at api/src/main/java/io/grpc/Uri.java:710
* <p>This field is required.
*
* @return this, for fluent building
* @throws IllegalArgumentException if the scheme is invalid.
*/
@CanIgnoreReturnValue
public Builder setScheme(String scheme) {
return setRawScheme(scheme.toLowerCase(Locale.ROOT));
}
@CanIgnoreReturnValue
Builder setRawScheme(String scheme) {
if (scheme.isEmpty() || !alphaChars.get(scheme.charAt(0))) {
throw new IllegalArgumentException("Scheme must start with an alphabetic char");
}
for (int i = 0; i < scheme.length(); i++) {
char c = scheme.charAt(i);
if (!schemeChars.get(c)) {
throw new IllegalArgumentException("Invalid character in scheme at index " + i);
}
}
this.scheme = scheme;
return this;
}
/**
* Specifies the new URI's path component as a string of zero or more '/' delimited segments.
*
* <p>Path segments can consist of any string of codepoints. Codepoints that can't be encoded
* literally will be percent-encoded for you.
*
* <p>If a URI contains an authority component, then the path component must either be empty or
* begin with a slash ("/") character. If a URI does not contain an authority component, then
* the path cannot begin with two slash characters ("//").
*
* <p>This method interprets all '/' characters in 'path' as segment delimiters. If any of your
* segments contain literal '/' characters, call {@link #setRawPath(String)} instead.View on GitHub (pinned to 64daddc1f3)
Solutions
- Remove illegal characters from the scheme; use only [A-Za-z][A-Za-z0-9+.-]*
- Lowercase and trim the scheme before passing it in
- If parsing a full URI string, strip the 'scheme:' prefix correctly instead of splitting on ':' and including leftovers
- Validate the scheme with a regex before calling setScheme
Example fix
// before
builder.setScheme(schemeAndTarget.split(":")[0]); // may contain ':' remnants or '_'
// after
String scheme = schemeAndTarget.substring(0, schemeAndTarget.indexOf(':')).trim();
if (!scheme.matches("[A-Za-z][A-Za-z0-9+.-]*")) { throw new IllegalArgumentException(...); }
builder.setScheme(scheme.toLowerCase(Locale.ROOT)); Defensive patterns
Strategy: validation
Validate before calling
static boolean isValidScheme(String s) {
return s != null && s.matches("[A-Za-z][A-Za-z0-9+.\-]*");
}
if (!isValidScheme(scheme)) throw new IllegalArgumentException("bad scheme: " + scheme); Type guard
boolean isValidScheme(String s) { return s != null && !s.isEmpty() && s.matches("[A-Za-z][A-Za-z0-9+.\-]*"); } Try / catch
try { builder.setScheme(scheme); } catch (IllegalArgumentException e) { log.error("Scheme rejected: {}", scheme, e); throw new ConfigException("Invalid URI scheme: " + scheme); } Prevention
- Use only standard schemes like https or dns
- Regex-validate schemes built from dynamic input
- Trim and lowercase before setting
- Never hand-concatenate URI schemes
When it happens
Trigger: Calling Uri.Builder.setScheme(String) or the create(...) factory with a scheme containing illegal characters such as spaces, underscores, colons, or symbols, e.g. 'my_scheme' or 'h tt p'.
Common situations: Building a target URI from user input or environment config where the scheme was hand-assembled instead of using standard 'https'/'dns'; typos like 'grpc://' parsed with the trailing colon included; interpolating values into a scheme string.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Scheme must start with an alphabetic char
- Invalid host or port:
- Has authority -- Non-empty path must start with '/'
- No authority -- Path cannot start with '//'
- Missing required scheme.
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/86dbe98169440249.
Report an issue: GitHub.