grpc/grpc-java · error · IllegalArgumentException

value ' ' for key ' ' is not an integer

Error message

value '%s' for key '%s' is not an integer

What it means

getNumberAsInteger also accepts string-encoded integers. If the value is a String that Integer.parseInt cannot parse, it rethrows as IllegalArgumentException with the key and offending value. This keeps config parsing strict rather than letting a malformed string become a default or NumberFormatException.

Solutions

  1. Fix the config value: use a valid 32-bit integer, either unquoted or as a clean numeric string ("3", not "3.0" or "three").
  2. Trim/normalize the value in your config pipeline before it reaches gRPC parsing.
  3. Validate config JSON with your own schema before passing it to gRPC so the failure surfaces with your own message.

Example fix

// before
{"maxInboundMessageSize": "4 MB"}
// after
{"maxInboundMessageSize": 4194304}
Defensive patterns

Strategy: validation

Validate before calling

Object v = config.get("retryAttempts");
if (v instanceof String) {
  try { Integer.parseInt((String) v); }
  catch (NumberFormatException e) { throw new IllegalArgumentException("retryAttempts is not an integer string"); }
}

Type guard

boolean isIntString(Object v) {
  if (!(v instanceof String)) return false;
  try { Integer.parseInt((String) v); return true; } catch (NumberFormatException e) { return false; }
}

Try / catch

try {
  int n = JsonUtil.getNumberAsInteger(config, "retryAttempts");
} catch (IllegalArgumentException e) {
  log.error("Invalid integer value in config: " + e.getMessage());
}

Prevention

When it happens

Trigger: JsonUtil.getNumberAsInteger(map, key) where the value is a String like "abc", "1.5", "12 3", or "" (empty), or a numeric string with signs/whitespace that parseInt rejects.

Common situations: Service config JSON where numbers were quoted ("retryAttempts": "three" or "5.0"); values interpolated from env vars with stray whitespace or units like "100ms"; YAML/JSON mixups leaving values as strings.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at core/src/main/java/io/grpc/internal/JsonUtil.java:147

  public static Integer getNumberAsInteger(Map<String, ?> obj, String key) {
    assert key != null;
    if (!obj.containsKey(key)) {
      return null;
    }
    Object value = obj.get(key);
    if (value instanceof Double) {
      Double d = (Double) value;
      int i = d.intValue();
      if (i != d) {
        throw new ClassCastException("Number expected to be integer: " + d);
      }
      return i;
    }
    if (value instanceof String) {
      try {
        return Integer.parseInt((String) value);
      } catch (NumberFormatException e) {
        throw new IllegalArgumentException(
            String.format("value '%s' for key '%s' is not an integer", value, key));
      }
    }
    throw new IllegalArgumentException(
        String.format("value '%s' for key '%s' is not an integer", value, key));
  }

  /**
   * Gets a number from an object for the given key, casted to an long.  If the key is not
   * present, this returns null.  If the value does not represent a long integer, throws an
   * exception.
   */
  public static Long getNumberAsLong(Map<String, ?> obj, String key) {
    assert key != null;
    if (!obj.containsKey(key)) {
      return null;
    }
    Object value = obj.get(key);

View on GitHub (pinned to 64daddc1f3)