Java StringIndexOutOfBoundsException
Fix Java StringIndexOutOfBoundsException from substring and charAt calls with off-by-one indices or unchecked user input lengths.
Symptoms
- java.lang.StringIndexOutOfBoundsException: begin 0, end 5, length 3
- substring(0, n) fails on short strings
- charAt(i) throws when the string is empty
Possible causes
- end index exceeds length or begin > end
- charAt(0) on an empty string
- The input was assumed to be a fixed length
- A trimmed or split string is shorter than expected
Diagnosis steps
Read the lengths in the exception message
Interpretation
The message includes begin, end, and length, so you can see exactly which bound was violated.
Validate length before slicing
Interpretation
Guard with if (s.length() >= n) or use Math.min to clamp indices.
Trace the string source
Interpretation
If the value comes from user input, encoding, or a split, empties and short values are expected.
Root cause
String substring and charAt enforce bounds: an end index beyond the string length, begin > end, or an index on an empty string throws StringIndexOutOfBoundsException. It is an unchecked exception, so only validation or clamped indices prevent it.
Fix
Validate length before extracting, clamp end with Math.min(end, s.length()), and check for empty strings before charAt. Prefer modern helpers such as s.startsWith/endsWith and regex extraction. For fixed-width parsing, reject inputs that are too short with a domain-specific exception instead of letting the index error escape.
Verify the fix
Re-run with the previously failing and a shorter input in a test; both are handled without throwing, and the short case produces the intended fallback or clear error.
Symptoms
A substring or charAt call throws StringIndexOutOfBoundsException: begin 0, end 5, length 3. It appears on short or empty input while longer values work.
Diagnosis
Read the bounds from the message and check length first:
String s = readInput();
System.out.println(s.length());
String head = s.substring(0, Math.min(5, s.length()));
If the source is user input or a split result, empty values are expected.
Fix
Validate or clamp before extracting:
if (s.isBlank()) {
throw new IllegalArgumentException("empty input");
}
int end = Math.min(5, s.length());
String head = s.substring(0, end);
char first = s.isEmpty() ? '\0' : s.charAt(0);
Verification
Test with both the failing input and a shorter string; neither throws, and the short case yields the documented fallback or clear domain error.
Reading the Bounds Message
The exception text is more helpful than it looks: begin 0, end 5, length 3 tells you the requested range and the real size in one line. When begin is greater than end the bug is reversed indices; when end exceeds length the caller assumed more characters than exist. Encoding-aware code must be careful too, because a multi-byte character occupies one index but several bytes, so slicing by byte offset after decoding, or decoding after slicing, produces mismatches that look like ordinary off-by-one errors.