javaseverity: workaround
NumberFormatException

Java NumberFormatException — String cannot be parsed as a number

NumberFormatException: invalid numeric string

99% fixable~8 mindifficulty: beginner

Verified against OpenJDK 21 documentation, Java SE API docs Integer.parseInt, JLS §4.2 · Updated June 2026

> quick_fix

Wrap the parse call in a try-catch or validate the string with a regex/null check before calling Integer.parseInt(). For optional numeric input, provide a default value on failure.

// Safe parse with try-catch
public static int parseIntSafe(String s, int defaultValue) {
    try {
        return Integer.parseInt(s);
    } catch (NumberFormatException e) {
        return defaultValue;
    }
}

// Usage
int value = parseIntSafe(request.getParameter("count"), 0);

// Java 8+: using Optional
Optional<Integer> parsed = Optional.ofNullable(s)
    .filter(str -> str.matches("-?\\d+"))
    .map(Integer::parseInt);

What causes this error

NumberFormatException is thrown by Integer.parseInt(), Long.parseLong(), Double.parseDouble(), and similar methods when the input string is null, empty, contains non-numeric characters, has leading/trailing whitespace, or represents a value outside the numeric type's range.

> advertisementAdSense placeholder

How to fix it

  1. 01

    step 1

    Check the input string value

    Log the string just before the parse call: `System.out.println("Parsing: '" + s + "'")`. Common culprits are empty strings (""), whitespace (" 42"), commas in large numbers ("1,000"), currency symbols ("$99"), or the literal string "null".

  2. 02

    step 2

    Trim whitespace before parsing

    User input and query parameters often carry leading or trailing spaces. Always call `.trim()` before parsing: `Integer.parseInt(s.trim())`. This handles the most common form-input NumberFormatException.

  3. 03

    step 3

    Validate with a regex or isEmpty check

    Before parsing, check the string is not null or empty: `if (s == null || s.isBlank()) return defaultValue;`. For integers: `s.matches("-?\\d+")`. For decimals: `s.matches("-?\\d+(\\.\\d+)?")`. Validate before, not after.

  4. 04

    step 4

    Handle locale-specific number formats

    Strings like "1,234.56" or "1.234,56" (European format) cannot be parsed by Double.parseDouble(). Use NumberFormat or DecimalFormat with the appropriate Locale: `NumberFormat.getInstance(Locale.GERMANY).parse(s)`.

  5. 05

    step 5

    Use the right type for the value's range

    Integer.parseInt() fails if the number is larger than Integer.MAX_VALUE (2,147,483,647). Use Long.parseLong() for larger values. For arbitrary precision, use new BigDecimal(s) which accepts any numeric string.

How to verify the fix

  • Test with edge-case inputs: null, empty string, whitespace-only, letters mixed in, very large numbers
  • Confirm that the default/fallback value is applied when invalid input is supplied
  • Check logs — no uncaught NumberFormatException stack traces

Why NumberFormatException happens at the runtime level

Integer.parseInt() and related methods implement a strict character-by-character parser that accepts only an optional leading minus sign followed by ASCII digits. Any deviation — whitespace, commas, decimal points, currency symbols, or a string that is null or empty — causes the method to throw NumberFormatException. The method does not perform locale-aware parsing; that responsibility is delegated to the NumberFormat/DecimalFormat family. This strict design is intentional to keep the core parse methods fast and predictable.

Common debug mistakes for NumberFormatException

  • Not calling .trim() on user input before parsing — a space before the number is invisible in logs
  • Parsing query parameters directly without a null/empty check — missing parameters return null from getParameter()
  • Using Integer.parseInt() for values that can exceed 2.1 billion (Unix timestamps, IDs from large databases)
  • Parsing formatted currency or percentage strings ("₹1,299", "45%") without stripping non-numeric characters first

When NumberFormatException signals a deeper problem

NumberFormatException at runtime is almost always an input validation gap — the application accepts external string data and converts it to a number without defending against malformed input. The systemic fix is to validate and coerce at the boundary (controller/DTO layer) before the value enters the domain model, using a consistent parse utility that returns a default or throws a meaningful domain exception rather than exposing the raw NumberFormatException to upper layers.

Editor's take

NumberFormatException in Java fires when you pass a string to `Integer.parseInt()`, `Double.parseDouble()`, or similar methods and the string cannot be interpreted as the target numeric type. It's one of the most frequently encountered exceptions in web backends because user input from HTTP parameters, form fields, and CSV imports is always a string — and users submit surprisingly creative non-numeric content. The production-grade pattern is to never use `parseInt()` directly on untrusted input without wrapping it in a try-catch or using a validation library first. In Spring Boot applications, the framework's `@RequestParam` binding handles this automatically and returns a 400 Bad Request, but if you're parsing manually in service layers, the exception propagates as an unhandled 500. Common gotchas: leading/trailing whitespace (use `.trim()` first), locale-specific thousands separators (German uses dots: "1.234"), hex strings without the `0x` prefix, and numeric strings that exceed `Integer.MAX_VALUE` but would fit in a `Long`. Since Java 9, `Optional`-returning parse methods haven't materialized in the standard library, but Apache Commons `NumberUtils.toInt(str, defaultValue)` provides a clean fallback pattern. Understanding where NumberFormatException fires is essentially understanding the boundary between string-typed external data and your application's internal numeric types.

By Bikram Nath · Curator · Updated June 2026

Frequently asked questions

Why does Integer.parseInt("1,000") throw NumberFormatException?

parseInt() does not understand locale-specific grouping separators. You must strip commas first: `s.replace(",", "")`, or use NumberFormat.getInstance(Locale.US).parse(s) which handles the grouping separator properly.

Is NumberFormatException checked or unchecked?

It is unchecked (extends IllegalArgumentException, which extends RuntimeException). You are not required to catch it at compile time, but you should handle it whenever parsing user-supplied or external data.

How do I parse a hex string in Java?

Use Integer.parseInt(s, 16) for hexadecimal. The string must not have a '0x' prefix — strip it first if present: `Integer.parseInt(s.startsWith("0x") ? s.substring(2) : s, 16)`.

disclosure:Errordex runs AdSense, has zero third-party affiliate or sponsored links, and occasionally links to the editor’s own paid digital products (clearly labelled). Every fix is cross-referenced against the official sources listed in the “sources” sidebar before it ships. If a fix here didn’t work for you, please email so we can update the page.