grpc/grpc-java · error · IllegalArgumentException

Invalid port

Error message

Invalid port

What it means

Thrown by Uri.Builder.setRawPort when the port string is non-empty but not parseable as an integer via Integer.parseInt. The raw port is stored as a string, but it must still be numerically valid so it can later be interpreted as a port number.

Source

Thrown at api/src/main/java/io/grpc/Uri.java:970

     *
     * <p>This field is optional.
     *
     * @param port the new "port" component, or -1 to clear this field
     * @return this, for fluent building
     */
    @CanIgnoreReturnValue
    public Builder setPort(int port) {
      this.port = port < 0 ? null : Integer.toString(port);
      return this;
    }

    @CanIgnoreReturnValue
    Builder setRawPort(String port) {
      if (port != null && !port.isEmpty()) {
        try {
          Integer.parseInt(port); // Result unused.
        } catch (NumberFormatException e) {
          throw new IllegalArgumentException("Invalid port", e);
        }
      }
      this.port = port;
      return this;
    }

    /**
     * Specifies the userinfo, host and port URI components all at once using a single string.
     *
     * <p>This setter is "raw" in the sense that special characters in userinfo and host must be
     * passed in percent-encoded. See <a
     * href="https://datatracker.ietf.org/doc/html/rfc3986#section-3.2">RFC 3986 3.2</a> for the set
     * of characters allowed in each component of an authority.
     *
     * <p>There's no "cooked" method to set authority like for other URI components because
     * authority is a *compound* URI component whose userinfo, host and port components are
     * delimited with special characters '@' and ':'. But the first two of those components can
     * themselves contain these delimiters so we need percent-encoding to parse them unambiguously.

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Ensure the port string is all digits before building the URI
  2. Trim whitespace and strip quotes from port config values
  3. Parse/validate with Integer.parseInt yourself and report a clearer message
  4. Omit the port entirely (null/empty) instead of passing a placeholder

Example fix

// before
builder.setHost(host).setRawPort(System.getenv("PORT"));
// after
String port = System.getenv("PORT");
if (port != null && !port.trim().isEmpty()) {
  Integer.parseInt(port.trim()); // fail fast with clearer message
  builder.setHost(host).setRawPort(port.trim());
}
Defensive patterns

Strategy: validation

Validate before calling

static Integer parsePort(String s) {
  if (s == null || s.trim().isEmpty()) return null;
  try { return Integer.valueOf(s.trim()); } catch (NumberFormatException e) { return null; }
}

Type guard

boolean isValidPort(String s) { if (s == null || s.isEmpty()) return true; try { Integer.parseInt(s); return true; } catch (NumberFormatException e) { return false; } }

Try / catch

try { builder.setRawPort(portStr); } catch (IllegalArgumentException e) { throw new ConfigException("Port is not numeric: " + portStr, e); }

Prevention

When it happens

Trigger: Calling setRawPort or building a URI whose authority contains a port segment that is non-numeric, e.g. 'host:8o80', 'host:port', or 'host:8080x'.

Common situations: Concatenating host and port from config where the port variable was mis-typed or contains a trailing character; environment variable ports with whitespace or quotes; copying 'host:port' placeholders literally.

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


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/e0b0b43b814b6579. Report an issue: GitHub.