🔴 The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOGjava.util.InputMismatchException at java.base/java.util.Scanner.throwFor(Scanner.java:977) at java.base/java.util.Scanner.next(Scanner.java:1632) at java.base/java.util.Scanner.nextInt(Scanner.java:2297)

⚡ Quick Fix Works 80% of the time

Gate typed reads with hasNextInt() and discard rejected tokens.

if (sc.hasNextInt()) { int age = sc.nextInt(); } else { sc.next(); // consume the invalid token before retrying }

🧠 Why this Happens

Tap to expand the deep technical explanation

Scanner validates each token against a regex built for the requested type and radix. On mismatch, throwFor raises InputMismatchException while deliberately leaving the scan position untouched so corrected input could be re-read. A value outside Integer.MIN_VALUE/MAX_VALUE lands here too even though it looked numeric, because conversion overflows during validation. Unconsumed tokens plus while(sc.hasNext()) retry logic produce the infamous infinite prompt loop.

The HITEC City Parking Spot Analogy:

A form asking date of birth receives your phone number: the clerk hands back the SAME unchanged form until you replace what you wrote.

🔁 How to Reproduce Confirm this is your error

Scanner sc = new Scanner("abc"); int n = sc.nextInt(); // InputMismatchException, "abc" still queued

🛠️ Solutions (5 Ways to Fix)

Solution 1✓ Most common cause

Gate reads with hasNextInt()/hasNextDouble()

👉 Use this if you control the read loop and can branch on validity before consuming.

The hasNext family applies the same pattern check without advancing, so invalid tokens can be inspected and discarded explicitly.

while (!sc.hasNextInt()) { System.out.print("Enter a number: "); sc.next(); // echo/discard the bad token } int value = sc.nextInt();
Solution 2

Flush the rejected token before reprompting

👉 Use this if you catch InputMismatchException inside a try/catch retry loop.

Without consuming something after the failure, the loop re-reads the same garbage forever; sc.nextLine() discards the rest of the offending line.

try { count = sc.nextInt(); } catch (InputMismatchException e) { sc.nextLine(); // drop the bad line System.out.println("Numbers only, try again."); }
Solution 3

Parse manually with Integer.parseInt

👉 Use this if you need distinct handling for wrong-format versus out-of-range values.

Reading the token as text routes failures through NumberFormatException where you choose the message and recovery per cause instead of one opaque mismatch.

String tok = sc.next(); try { int v = Integer.parseInt(tok); } catch (NumberFormatException e) { System.out.println(tok + " is not a valid int"); }
Solution 4

Set locale/radix explicitly

👉 Use this if inputs come from users whose decimal separator differs (3,14 vs 3.14) or from hex strings.

Scanner formats follow its Locale and radix; useLocale(Locale.GERMANY) accepts comma decimals and useRadix(16) reads hex ints deterministically.

Scanner sc = new Scanner(System.in).useLocale(Locale.GERMANY); double price = sc.nextDouble(); // accepts 19,99
Solution 5

Line-first architecture: read, split, validate

👉 Use this if building robust CLIs or bulk importers where one bad row must not kill the run.

Read whole lines, split on delimiter, validate each field, and report row numbers - errors become data-quality findings instead of crashes.

String[] f = sc.nextLine().split(","); int qty = Integer.parseInt(f[1].trim()); // report field errors with context

📋 Version Notes

Java 8

Identical semantics; token stays unconsumed after the throw.

Java 11+

Unchanged. hasNextInt uses radix 10 unless useRadix() sets another.

🛡️ How to Prevent This Next Time

Never assume console or file content types; treat Scanner as a pattern matcher. In any retry loop, always discard rejected tokens before asking again.