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
- Fix the config value: use a valid 32-bit integer, either unquoted or as a clean numeric string ("3", not "3.0" or "three").
- Trim/normalize the value in your config pipeline before it reaches gRPC parsing.
- 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
- Avoid quoting numeric config values in JSON.
- Trim values derived from env vars before injecting them into config.
- Reject strings with units ("100ms") at config-load time.
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
- value ' ' for key ' ' is not a long integer
- Authorization policy should be a JSON object. Found: null
- Number expected to be integer:
- Number expected to be long:
- value for idx in is not object
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)