jwtk/jjwt · error · IllegalArgumentException
Value must be a positive integer.
Error message
Value must be a positive integer.
What it means
Thrown by PositiveIntegerConverter.applyFrom when a raw value destined for a parameter that must be a positive integer either cannot be converted to an int (overflow, fractional number, non-numeric string) or converts to a value <= 0. It is a parameter-conversion guard: the offending input is whatever Object was passed for that parameter (e.g. an expiration/leeway-style setting).
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/lang/PositiveIntegerConverter.java:51
Assert.notNull(o, "Argument cannot be null.");
int i;
if (o instanceof Byte || o instanceof Short || o instanceof Integer || o instanceof AtomicInteger) {
i = ((Number) o).intValue();
} else { // could be Long, AtomicLong, Float, Decimal, BigInteger, BigDecimal, String, etc., all of which
// may not be accurately converted into an Integer, either due to overflow or fractional values. The
// easiest way to account for all of them is to parse the string value as an int instead of testing all
// the types:
String sval = String.valueOf(o);
try {
i = Integer.parseInt(sval);
} catch (NumberFormatException e) {
String msg = "Value cannot be represented as a java.lang.Integer.";
throw new IllegalArgumentException(msg, e);
}
}
if (i <= 0) {
String msg = "Value must be a positive integer.";
throw new IllegalArgumentException(msg);
}
return i;
}
}
View on GitHub (pinned to fb71496164)
Solutions
- Ensure the value is >= 1 before passing it.
- Clamp or validate: if (v <= 0) throw/adjust before setting the claim.
- Check upstream computation for off-by-one or sign errors that produced the non-positive value.
Example fix
// before
long seconds = (end - start) / 1000; // could be 0
jwtBuilder.claim("ttl", (int) seconds);
// after
int seconds = Math.max(1, (int) ((end - start) / 1000));
jwtBuilder.claim("ttl", seconds); Defensive patterns
Strategy: validation
Validate before calling
int requirePositive(int v) {
if (v <= 0) throw new IllegalArgumentException("Value must be a positive integer, got: " + v);
return v;
} Try / catch
try {
converter.applyFrom(value);
} catch (IllegalArgumentException e) {
if ("Value must be a positive integer.".equals(e.getMessage())) {
// clamp or reject the non-positive input
}
throw e;
} Prevention
- Validate >= 1 at boundaries where the value is computed or configured
- Beware of defaults of 0 for counters, TTLs and limits
- Check subtraction-based computations for negative/zero results
When it happens
Trigger: Passing 0 or a negative number (or a string like "0", "-3") to any claim/converter configured with PositiveIntegerConverter.
Common situations: Zero initialized counters used as default values; negative offsets; computing a value like timeout = end - start that evaluated to <= 0.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- ${i.getClass()} getId() cannot be null or empty.
- Value cannot be represented as a java.lang.Integer.
- Byte array must be exactly ${bitsMsg(this.bitLength)}. Found
- Byte array must be at least ${bitsMsg(this.bitLength)}. Foun
- Unsupported value type. Expected: ${type.getName()}, found:
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/75e55db7b766fe5c.
Report an issue: GitHub.