Fix: Java java.lang.IllegalArgumentException
Quick Answer
How to fix Java IllegalArgumentException caused by null arguments, invalid enum values, negative numbers, wrong format strings, and Spring/Hibernate validation failures.
The Error
Your Java application throws:
java.lang.IllegalArgumentException: argument type mismatchOr variations:
java.lang.IllegalArgumentException: No enum constant com.example.Status.UNKNOWNjava.lang.IllegalArgumentException: Invalid character found in method namejava.lang.IllegalArgumentException: Comparison method violates its general contract!java.lang.IllegalArgumentException: bound must be positivejava.lang.IllegalArgumentException: Name for argument of type [java.lang.String] not specifiedA method received an argument that is not valid according to its contract. The argument has the correct type (it compiled), but its value is not acceptable.
Why This Happens
IllegalArgumentException is thrown when a method receives an argument that fails a precondition check. Unlike NullPointerException (which is unintentional), IllegalArgumentException is explicitly thrown by code that validates its inputs.
Common causes:
- Null passed where non-null is required. A method explicitly rejects null.
- Out-of-range value. A negative number where only positives are allowed.
- Invalid enum name.
Enum.valueOf()with a string that does not match any constant. - Format mismatch. A date string that does not match the expected pattern.
- Comparator contract violation. A
Comparatorthat is not transitive or consistent. - Reflection argument mismatch. Calling a method via reflection with wrong argument types.
- Spring/Hibernate validation. Framework-level validation rejects input values.
Fix 1: Validate Arguments Before Passing
Check the value before calling the method:
Broken — passing invalid value:
// Random.nextInt(bound) requires bound > 0
Random random = new Random();
int result = random.nextInt(0); // IllegalArgumentException: bound must be positiveFixed:
Random random = new Random();
int bound = getBound();
if (bound <= 0) {
throw new IllegalArgumentException("Bound must be positive, got: " + bound);
// or use a default
bound = 1;
}
int result = random.nextInt(bound);Common methods that throw IllegalArgumentException:
| Method | Requirement |
|---|---|
Random.nextInt(bound) | bound > 0 |
String.substring(begin, end) | 0 ≤ begin ≤ end ≤ length |
Arrays.copyOfRange(arr, from, to) | from ≤ to |
Collections.nCopies(n, obj) | n ≥ 0 |
Thread.sleep(millis) | millis ≥ 0 |
Pro Tip: When you get an
IllegalArgumentException, read the message carefully. It usually tells you exactly what is wrong with the argument. The fix is almost always to validate the value before passing it to the method.
Fix 2: Fix Enum.valueOf() Errors
Enum.valueOf() throws IllegalArgumentException when the string does not match any constant:
Broken:
enum Status { ACTIVE, INACTIVE, PENDING }
String input = "UNKNOWN";
Status status = Status.valueOf(input);
// IllegalArgumentException: No enum constant Status.UNKNOWNFixed — handle unknown values:
// Option 1: Try-catch
try {
Status status = Status.valueOf(input.toUpperCase());
} catch (IllegalArgumentException e) {
Status status = Status.PENDING; // Default value
}
// Option 2: Custom lookup method
public static Status fromString(String value) {
for (Status s : Status.values()) {
if (s.name().equalsIgnoreCase(value)) {
return s;
}
}
return Status.PENDING; // Default
}
// Option 3: Use a Map for O(1) lookup
private static final Map<String, Status> LOOKUP = Arrays.stream(Status.values())
.collect(Collectors.toMap(Enum::name, Function.identity()));
public static Optional<Status> fromString(String value) {
return Optional.ofNullable(LOOKUP.get(value.toUpperCase()));
}Jackson/JSON deserialization:
@JsonCreator
public static Status fromJson(String value) {
return Arrays.stream(Status.values())
.filter(s -> s.name().equalsIgnoreCase(value))
.findFirst()
.orElse(Status.PENDING);
}Common Mistake: Assuming user input will always match an enum constant exactly. Enum names are case-sensitive (
ACTIVE≠active). Always normalize the input (.toUpperCase()) or use case-insensitive comparison.
Fix 3: Fix Comparator Contract Violations
The error “Comparison method violates its general contract” means your Comparator is not transitive:
Broken:
// Inconsistent comparator — violates transitivity
list.sort((a, b) -> {
if (a.getScore() > b.getScore()) return 1;
if (a.getScore() < b.getScore()) return -1;
return 0; // Might not handle NaN or null correctly
});Broken — comparing doubles with floating-point issues:
list.sort((a, b) -> (int)(a.getPrice() - b.getPrice()));
// Casting to int loses precision: 0.5 - 0.3 = 0.2, (int)0.2 = 0 (treated as equal)Fixed — use built-in comparators:
// For primitives
list.sort(Comparator.comparingInt(Item::getScore));
list.sort(Comparator.comparingDouble(Item::getPrice));
// Multiple fields
list.sort(Comparator.comparing(Item::getCategory)
.thenComparingDouble(Item::getPrice)
.thenComparing(Item::getName));
// With null handling
list.sort(Comparator.comparing(Item::getName, Comparator.nullsLast(Comparator.naturalOrder())));Fixed — use Double.compare() for doubles:
list.sort((a, b) -> Double.compare(a.getPrice(), b.getPrice()));Fix 4: Fix Reflection Argument Mismatches
Calling methods via reflection with wrong argument types:
Broken:
Method method = MyClass.class.getMethod("process", int.class);
method.invoke(obj, "hello"); // IllegalArgumentException: argument type mismatchFixed — match the parameter types:
Method method = MyClass.class.getMethod("process", int.class);
method.invoke(obj, 42); // Correct type
// For primitive vs wrapper issues:
Method method = MyClass.class.getMethod("process", Integer.class); // Use Integer, not int
method.invoke(obj, Integer.valueOf(42));Check parameter types before invoking:
Method method = MyClass.class.getMethod("process", int.class);
Class<?>[] paramTypes = method.getParameterTypes();
System.out.println(Arrays.toString(paramTypes)); // [int]Fix 5: Fix Date and Time Parsing
Invalid date/time formats cause IllegalArgumentException:
Broken:
// Wrong format
LocalDate date = LocalDate.parse("03/15/2024");
// IllegalArgumentException (or DateTimeParseException which extends it)
// Wrong value
LocalDate date = LocalDate.of(2024, 13, 1); // Month 13 doesn't existFixed:
// Specify the format
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
LocalDate date = LocalDate.parse("03/15/2024", formatter);
// Validate before parsing
public static Optional<LocalDate> parseDate(String input, String pattern) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return Optional.of(LocalDate.parse(input, formatter));
} catch (DateTimeParseException e) {
return Optional.empty();
}
}Fix 6: Fix Spring Framework Errors
Spring commonly throws IllegalArgumentException for configuration issues:
Missing request parameter:
IllegalArgumentException: Name for argument of type [java.lang.String] not specifiedFixed — use @RequestParam with name:
@GetMapping("/search")
public ResponseEntity<List<Item>> search(@RequestParam("q") String query) {
return ResponseEntity.ok(service.search(query));
}Bean validation errors:
@PostMapping("/users")
public ResponseEntity<User> create(@Valid @RequestBody UserRequest request) {
// @Valid triggers bean validation
// If validation fails, MethodArgumentNotValidException is thrown
}
public record UserRequest(
@NotBlank String name,
@Email String email,
@Min(0) @Max(150) int age
) {}Property resolution:
IllegalArgumentException: Could not resolve placeholder 'api.key' in value "${api.key}"Fixed — add the property or provide a default:
@Value("${api.key:default-value}")
private String apiKey;Or add it to application.properties:
api.key=your-key-hereFix 7: Fix Collection and Array Operations
Arrays.asList() with primitives:
int[] numbers = {1, 2, 3};
List<int[]> list = Arrays.asList(numbers); // Creates a List of one int[] element!
// Fixed — use Integer[]
Integer[] numbers = {1, 2, 3};
List<Integer> list = Arrays.asList(numbers);
// Or use streams
List<Integer> list = Arrays.stream(new int[]{1, 2, 3}).boxed().toList();Collections.unmodifiableList() modifications:
List<String> immutable = Collections.unmodifiableList(original);
immutable.add("new"); // UnsupportedOperationException, not IllegalArgumentException
// But some operations throw IllegalArgumentExceptionMap.of() with duplicate keys:
Map<String, Integer> map = Map.of("a", 1, "a", 2);
// IllegalArgumentException: duplicate key: aFix 8: Write Defensive Methods
Add argument validation to your own methods:
public class UserService {
public User createUser(String name, String email, int age) {
// Java's Objects utility
Objects.requireNonNull(name, "name must not be null");
Objects.requireNonNull(email, "email must not be null");
// Custom validation
if (name.isBlank()) {
throw new IllegalArgumentException("name must not be blank");
}
if (age < 0 || age > 150) {
throw new IllegalArgumentException("age must be between 0 and 150, got: " + age);
}
if (!email.contains("@")) {
throw new IllegalArgumentException("invalid email: " + email);
}
return new User(name, email, age);
}
}Using Guava Preconditions:
import com.google.common.base.Preconditions;
public void transfer(Account from, Account to, BigDecimal amount) {
Preconditions.checkNotNull(from, "from account must not be null");
Preconditions.checkNotNull(to, "to account must not be null");
Preconditions.checkArgument(amount.compareTo(BigDecimal.ZERO) > 0,
"amount must be positive, got: %s", amount);
}Still Not Working?
Check the full stack trace. The exception message and the stack trace tell you which method threw the exception and what argument was invalid.
Check for version mismatches. Library upgrades can change validation rules. A method that accepted null in v1 might reject it in v2.
Check for thread safety. Concurrent access to non-thread-safe collections (HashMap, ArrayList) can cause IllegalArgumentException with confusing messages like “Comparison method violates its general contract.”
For Java null pointer errors, see Fix: Java NullPointerException. For class loading issues, see Fix: Java ClassNotFoundException. For Spring Boot startup errors, see Fix: Spring BeanCreationException.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: Java ClassCastException: class X cannot be cast to class Y
How to fix Java ClassCastException by using instanceof checks, fixing generic type erasure, resolving ClassLoader conflicts, correcting raw types, and using pattern matching in Java 16+.
Fix: Java ConcurrentModificationException
How to fix Java ConcurrentModificationException caused by modifying a collection while iterating, HashMap concurrent access, stream operations, and multi-threaded collection usage.
Fix: Java NoSuchMethodError
How to fix Java NoSuchMethodError caused by classpath conflicts, incompatible library versions, wrong dependency scope, shaded JARs, and compile vs runtime version mismatches.
Fix: Java java.lang.NullPointerException
How to fix Java NullPointerException by reading stack traces, adding null checks, using Optional, fixing uninitialized variables, avoiding null returns, handling auto-unboxing, and using static analysis annotations.