java.lang.NumberFormatException: For input string: "X"

Quick answer

  • Read the quoted value literally. The characters between the quotes are the exact input the parser choked on.
  • "" = empty/missing upstream value. " 42" = untrimmed whitespace (parseInt never trims).
  • Looks valid but still fails? A hidden character — a BOM (U+FEFF) or non-breaking space (U+00A0). Print s.length() and the char codes.
  • "1,234" = grouping separator (use NumberFormat); "42.0" = decimal point (use Double.parseDouble); a huge number = int overflow (use Long.parseLong).

The exact error string

The stack trace names the parser and the offending value. The value in quotes is the whole story:

Exception in thread "main" java.lang.NumberFormatException: For input string: "1,234"
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
    at java.base/java.lang.Integer.parseInt(Integer.java:668)
    at java.base/java.lang.Integer.parseInt(Integer.java:786)
    at com.example.App.main(App.java:7)

You will also see these variants — same exception, different quoted content, and sometimes a trailing under radix N:

NumberFormatException: For input string: ""                 // empty string
NumberFormatException: For input string: " 42"             // leading space (not trimmed)
NumberFormatException: For input string: "42.0"            // decimal point, parsed as int
NumberFormatException: For input string: "null"            // the literal text "null"
NumberFormatException: For input string: "12345678901"     // overflows int range
NumberFormatException: For input string: "FF" under radix 10   // hex without radix 16
NumberFormatException: null                                // Integer.parseInt(null) — different message

The exception comes from Integer.parseInt, Long.parseLong, Double.parseDouble, new BigDecimal(...), or any similar parser that was handed a string it can't read as a number in the format it expects. Unlike many errors, this one hands you the failing input directly — so the fastest path to a fix is to decode what's between the quotes.

Anatomy of the message — the quotes are the input

The message is literally For input string: " + the exact CharSequence you passed + ". Whatever sits between those quotes is the raw value, character for character. The trap is that some of those characters are invisible: a trailing space shows as "42 " and is easy to miss, while a BOM or non-breaking space shows as nothing at all even though it's there. So the first move is always: copy the quoted content and look at what it actually contains.

This table maps the quoted value to its cause and fix — find your row:

What's in the quotesWhat it meansFix
"" (empty)Missing upstream value — blank field, absent JSON keyCheck empty/null first; supply a default
" 42" / "42\n"Whitespace; parseInt does not trims.trim() (or strip()) before parsing
Looks like "42" but failsHidden char — BOM U+FEFF or NBSP U+00A0Print length + char codes; strip the char
"1,234" / "1.234"Thousands/grouping separator (locale)Use NumberFormat, or remove separators
"42.0" / "3.14"Decimal point given to an integer parserUse Double.parseDouble / BigDecimal
"12345678901"Value exceeds int range (±2.1 billion)Use Long.parseLong / BigInteger
"null" / "undefined"A null/undefined got stringified upstreamFix the source; treat as missing
"0x1F" / "FF"Non-decimal digits with the default radix 10parseInt(s, 16) or Integer.decode

Fix 1: trim first — parseInt does not

A surprising number of these are just whitespace. Integer.parseInt accepts only an optional sign and digits; a single leading or trailing space fails it. Values pulled from a file, a form, or a split CSV column routinely carry them:

Integer.parseInt(" 42");   // throws: For input string: " 42"
Integer.parseInt("42 ");   // throws: For input string: "42 "

Integer.parseInt(" 42".trim());    // 42  (Java: trim removes ASCII whitespace)
Integer.parseInt(" 42 ".strip());  // 42  (Java 11+: strip is Unicode-aware, also removes NBSP-like spaces)

Prefer strip() on Java 11+ — it's Unicode-aware and removes several space characters that trim() leaves behind, which is exactly what you want when the culprit is a stray non-breaking space.

Fix 2: a value that "looks fine" — find the hidden character

When the quoted value looks like a perfectly good number and still fails, there is an invisible character in it. The two usual offenders are the byte-order mark (U+FEFF, code 65279) at the start of a UTF-8 file's first field, and a non-breaking space (U+00A0, code 160) from data copied out of a web page or spreadsheet. Prove it by printing the length and the code points:

String s = readFirstColumn();      // looks like "42" in the console
System.out.println(s.length());    // 3  <- one char too many!
s.chars().forEach(c -> System.out.printf("%d ", c));
// 65279 52 50   <- a BOM (65279) is hiding in front of '4' '2'

// strip anything that isn't a digit or sign, then parse
int n = Integer.parseInt(s.replaceAll("[^0-9-]", ""));   // 42

If this value came from a JSON payload or an API response, inspect the raw body before you parse anything — paste it into the JSON Formatter to see the exact bytes and confirm whether the number arrived as a proper JSON number or as a quoted string with junk around it. A field that should be {"qty": 42} but is actually {"qty": " 42"} is the whole bug, visible at a glance.

Fix 3: grouping separators and locale (the comma)

Integer.parseInt has no concept of a thousands separator, so "1,234" throws. Either strip the separators, or — if the input is genuinely locale-formatted — parse it with a locale-aware NumberFormat:

import java.text.NumberFormat;
import java.util.Locale;

// locale-aware parse (throws java.text.ParseException, NOT NumberFormatException)
NumberFormat nf = NumberFormat.getInstance(Locale.US);
int n = nf.parse("1,234").intValue();     // 1234

// or just remove the grouping character before parseInt
int m = Integer.parseInt("1,234".replace(",", ""));   // 1234

Two gotchas with NumberFormat.parse: it throws java.text.ParseException rather than NumberFormatException, and it is lenient — it parses as far as it can and stops, so "12abc" returns 12 instead of failing. If you need strict all-or-nothing parsing, validate the string first or stick with parseInt on a cleaned value.

Fix 4: decimal points, overflow, and radix

Three more mismatches between the value and the parser you chose:

double d = Double.parseDouble("42.0");        // 42.0
long   l = Long.parseLong("12345678901");     // 12345678901
int    h = Integer.parseInt("FF", 16);        // 255
int    x = Integer.decode("0x1F");            // 31

Fix 5: parse defensively at trust boundaries

When the number comes from anything you don't control — a form field, a query parameter, an uploaded file, a JSON body — a bad value is a user problem, not a server crash. Don't let NumberFormatException bubble up into a 500. Validate or catch, and return a clean error:

static int parseQuantity(String raw) {
    if (raw == null || raw.isBlank()) {
        throw new IllegalArgumentException("quantity is required");
    }
    String s = raw.strip();
    if (!s.matches("-?\\d+")) {                     // shape-check before parsing
        throw new IllegalArgumentException("quantity must be a whole number, got: " + s);
    }
    try {
        return Integer.parseInt(s);
    } catch (NumberFormatException e) {             // still possible: overflow
        throw new IllegalArgumentException("quantity is too large: " + s);
    }
}

The regex rejects empty strings, decimals, and stray characters up front with a message that names the actual value, and the catch still handles the one case a shape-check can't — a well-formed run of digits that overflows int. This turns a stack trace into a validation message a caller can act on. It's the numeric cousin of guarding against a NullPointerException before you dereference.

Debugging checklist

Frequently Asked Questions

What does NumberFormatException: For input string mean?

A parser like Integer.parseInt, Long.parseLong, or Double.parseDouble was given a string that is not a valid number in the expected format. The exact characters between the quotes in the message are the literal input it tried to parse. Read them carefully — the value that failed is right there, including any whitespace or hidden characters.

Why does 'For input string: ""' happen with an empty string?

The input was an empty string. Integer.parseInt("") throws because there are no digits to parse. This usually means an upstream value was missing — an empty form field, an absent JSON property that arrived as "", or a config key with no value. Check for empty and null before parsing and supply a default.

Why does Integer.parseInt fail on a value that looks like a valid number?

There is almost always an invisible character. Integer.parseInt does not trim, so leading or trailing spaces fail. A copied value can also carry a byte-order mark (U+FEFF) or a non-breaking space (U+00A0) that renders as nothing. Print s.length() and the character codes — a "42" of length 3, or one containing code 65279 or 160, confirms a hidden character.

How do I parse a number with a comma like '1,234'?

Integer.parseInt does not understand grouping separators, so "1,234" fails. Strip the separators first, or use a locale-aware NumberFormat: NumberFormat.getInstance(Locale.US).parse("1,234").intValue() returns 1234. Note NumberFormat.parse throws java.text.ParseException, not NumberFormatException, and it stops at the first non-numeric character rather than rejecting the whole string.

Why does Integer.parseInt fail on '42.0'?

Integer.parseInt only accepts an optional sign and digits — no decimal point. "42.0" is a floating-point literal, so it throws. Use Double.parseDouble("42.0") for a double, or if you truly want an int, parse as a double and round or truncate, or split on the decimal point after validating the shape.

How do I parse safely without throwing NumberFormatException?

Trim and validate first, then parse inside a try/catch that returns a default on failure, or check the string against a regex like ^-?\d+$ before calling parseInt. Never let a NumberFormatException from untrusted input (a form, an API, a file) crash a request — catch it and return a clean validation error instead.

Inspect the payload, then fix the parse

When the number arrives inside JSON, look at the raw body first — then browse the full error reference.

All Error References JSON Formatter Java: NullPointerException
About the author

Pasindu Ishan is a software developer based in Sri Lanka. He builds privacy-first developer tools at JSON Dev Tools.