grpc/grpc-java · error · IllegalArgumentException
Has authority -- Non-empty path must start with '/'
Error message
Has authority -- Non-empty path must start with '/'
What it means
Uri's constructor validates RFC 3986 path/authority relationships. When the URI has an authority component, any non-empty path must start with '/'. Otherwise an IllegalArgumentException is thrown. This guards the invariant that hierarchical paths after an authority are root-relative.
Source
Thrown at api/src/main/java/io/grpc/Uri.java:185
@Nullable private final String host;
@Nullable private final String port;
private final String path; // In RFC 3986, path is always defined (but can be empty).
@Nullable private final String query;
@Nullable private final String fragment;
private Uri(Builder builder) {
this.scheme = checkNotNull(builder.scheme, "scheme");
this.userInfo = builder.userInfo;
this.host = builder.host;
this.port = builder.port;
this.path = builder.path;
this.query = builder.query;
this.fragment = builder.fragment;
// Checks common to the parse() and Builder code paths.
if (hasAuthority()) {
if (!path.isEmpty() && !path.startsWith("/")) {
throw new IllegalArgumentException("Has authority -- Non-empty path must start with '/'");
}
} else {
if (path.startsWith("//")) {
throw new IllegalArgumentException("No authority -- Path cannot start with '//'");
}
}
}
/**
* Parses a URI from its string form.
*
* @throws URISyntaxException if 's' is not a valid RFC 3986 URI.
*/
public static Uri parse(String s) throws URISyntaxException {
try {
return create(s);
} catch (IllegalArgumentException e) {
throw new URISyntaxException(s, e.getMessage());View on GitHub (pinned to 64daddc1f3)
Solutions
- Prefix the path with '/' when an authority is present and the path is non-empty
- If no path is desired, pass the empty string instead of a slash-less segment
- Recheck how the URI string is split into authority and path; use Uri.parse() rather than manual string slicing
Example fix
// before
Uri.newBuilder().setScheme("https").setHost("example.com").setPath("api") // throws
// after
Uri.newBuilder().setScheme("https").setHost("example.com").setPath("/api").build(); Defensive patterns
Strategy: validation
Validate before calling
if (hasAuthority && !path.isEmpty() && !path.startsWith("/")) path = "/" + path; Try / catch
try {
uri = builder.build();
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Malformed URI: " + e.getMessage(), e);
} Prevention
- When an authority is set, always make paths absolute (leading '/')
- Use Uri.parse() on full strings instead of assembling builder fields from raw slices
- Add unit tests for authority+path combinations
When it happens
Trigger: Building a Uri with setAuthority(...) and then setPath("foo") (no leading slash), or parsing a string like "scheme://hostfoo" where the path portion is non-empty and lacks a leading '/'.
Common situations: Hand-assembling target/authority strings for gRPC channels (e.g. authority "host:8080" plus a path missing its slash); mis-parsing URIs where the authority and path were split incorrectly; constructing links from concatenated strings.
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.
Related errors
- No authority -- Path cannot start with '//'
- Missing required scheme.
- Scheme must start with an alphabetic char
- Invalid host or port:
- Invalid character in scheme at index ${i}
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/1bd2e302b492c73f.
Report an issue: GitHub.