One-Time Password (OTP) Regex
Validates that a string is a numeric one-time password between 4 and 8 digits long, matching the typical range used by SMS, email, and authenticator-app OTPs.
Regex Pattern
^\d{4,8}$Pattern Breakdown
Hover over a token to see what it does.
| Token | Meaning |
|---|---|
| ^ | Anchors the match to the start of the string |
| \d | Matches a single digit (0-9) |
| {4,8} | Requires between 4 and 8 digits, the common length range for OTPs |
| $ | Anchors the match to the end of the string |
Detailed Explanation
What it does
This pattern checks that the entire input string consists only of digits and is between 4 and 8 characters long, matching the shape of a typical numeric one-time password sent via SMS, email, or generated by an authenticator app.
Why it works
Most OTP schemes (TOTP/HOTP per RFC 6238/4226, and most SMS-based codes) generate a fixed-length numeric string, commonly 6 digits but sometimes as short as 4 or as long as 8. A simple bounded digit-count quantifier captures this whole common range without needing to know the exact length a given provider uses.
Common use cases
- Validating the shape of a code entered into a 2FA/OTP input field before checking it against the server
- Client-side format checks to give instant feedback before an OTP verification API call
- Filtering SMS message text to auto-extract a likely OTP code for autofill
- Rejecting obviously malformed input (letters, wrong length) before spending a verification attempt
Edge cases
- Codes with leading zeros, like '0042', are valid OTPs and are correctly matched since \d treats them as ordinary digits, not numbers
- Alphanumeric OTPs (some systems mix in letters) will not match this numeric-only pattern and need a separate pattern
- A code of exactly 4 or exactly 8 digits is accepted since the quantifier bounds are inclusive
- Whitespace around the code, like ' 123456', is rejected due to the anchors
Limitations
- Only validates shape, not correctness; the actual OTP must still be verified server-side against the expected value and expiry window
- Does not enforce a single fixed length; if your system always uses exactly 6 digits, a tighter {6} pattern is more precise
- Does not support alphanumeric or hyphenated OTP formats used by some providers
- Cannot detect or prevent OTP brute-forcing; rate limiting must be handled separately
Interactive Tester
Edit the pattern or text below — matching runs live in your browser.
Test Cases
Editable — add your own inputs to see if they pass.
| Input | Expected | Result | |
|---|---|---|---|
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass |
Language Variants
Production-ready examples in 12 languages.
const otpRegex = /^\d{4,8}$/;
console.log(otpRegex.test('123456')); // trueCommon Mistakes
Treating a format-valid OTP string as an already-verified code
Fix: Always check the entered code against the server-generated value and its expiry window; regex only validates shape
Using a fixed {6} when the product actually supports variable-length OTPs across providers
Fix: Use the {4,8} range (or your exact supported lengths) so the input field doesn't reject valid shorter or longer codes
Allowing unlimited verification attempts because 'the regex passed'
Fix: Rate-limit and lock out OTP verification attempts server-side regardless of client-side format validation
Performance Notes
- A single bounded digit quantifier is O(n) with no backtracking risk
- This pattern is cheap enough to run on every keystroke for live input-field validation feedback
- Anchors ensure the whole field content is checked, not just a leading digit run
Browser Compatibility
| Engine | Supported | Notes |
|---|---|---|
| Chrome | Yes | — |
| Firefox | Yes | — |
| Safari | Yes | — |
| Edge | Yes | — |
| Node.js | Yes | — |