US Social Security Number Regex
Validates the format of a US Social Security Number (123-45-6789), rejecting area, group, and serial values that the SSA never issues, such as area 000, 666, or 900-999.
Regex Pattern
^(?!000|666|9\d{2})\d{3}-(?!00)\d{2}-(?!0000)\d{4}$Pattern Breakdown
Hover over a token to see what it does.
| Token | Meaning |
|---|---|
| ^ | Anchors the match to the start of the string |
| (?!000|666|9\d{2}) | Negative lookahead rejecting area numbers 000, 666, or any number starting with 9 (900-999), which the SSA never assigns |
| \d{3}- | The 3-digit area number followed by a literal hyphen |
| (?!00)\d{2}- | Negative lookahead rejecting group '00', then the 2-digit group number and a hyphen |
| (?!0000)\d{4}$ | Negative lookahead rejecting serial '0000', then the 4-digit serial number and end of string |
Detailed Explanation
What it does
This pattern validates that a string is in the standard AAA-GG-SSSS Social Security Number format while also rejecting known-invalid combinations: an area of 000, 666, or 900-999, a group of 00, or a serial of 0000, none of which the Social Security Administration has ever issued.
Why it works
Each `(?!...)` is a zero-width negative lookahead placed immediately before the digits it constrains, so it can reject a disallowed value before the corresponding `\d{n}` consumes it, without affecting what actually gets matched. Chaining three independent lookahead/digit-group pairs mirrors the SSA's own historical issuance rules segment by segment.
Common use cases
- Format-validating SSN input fields on US tax, payroll, or benefits enrollment forms
- Client-side pre-checks before submitting sensitive PII to a backend for encrypted storage
- Filtering documents or logs for SSN-shaped strings during a PII redaction pass
- Rejecting obviously fake test data like 000-00-0000 in QA environments
Edge cases
- Since 2011 the SSA uses randomized issuance, so the old geographic meaning of the area number no longer applies, but the never-issued ranges (000, 666, 900-999) are still permanently invalid
- SSNs without hyphens, like '123456789', are rejected by this pattern since it requires the hyphenated display format
- The famous placeholder '078-05-1120' (originally a sample SSN misused by many people) passes format validation despite widespread real-world misuse
- A format-valid SSN like '123-45-6789' may still not belong to any real person; this pattern cannot check issuance records
Limitations
- Cannot verify an SSN was actually issued or belongs to the claimed individual (needs SSA's official verification service)
- Does not detect known-compromised or breached SSNs
- Only validates the hyphenated display format; a companion pattern is needed for the unformatted 9-digit form
- Handling and storing SSNs requires strict security and compliance controls well beyond regex validation
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 ssnRegex = /^(?!000|666|9\d{2})\d{3}-(?!00)\d{2}-(?!0000)\d{4}$/;
console.log(ssnRegex.test('123-45-6789')); // trueCommon Mistakes
Assuming Go's or Rust's built-in regex engines support the negative lookaheads used here
Fix: RE2-based engines don't support lookahead; capture the digit groups and check the invalid ranges with plain string comparisons instead
Validating format only and treating a passing SSN as proof of identity
Fix: Format validation should be paired with proper KYC/identity verification, never used as identity proof on its own
Logging or storing SSNs in plaintext after validation for debugging
Fix: Mask all but the last 4 digits in logs and encrypt SSNs at rest per PII handling requirements
Performance Notes
- The negative lookaheads only inspect a few characters ahead each time, so they add negligible overhead over a plain digit-and-hyphen match
- Fixed-width digit groups mean no catastrophic backtracking is possible in this pattern
- Precompile and reuse the regex object across requests instead of recompiling per validation call
Browser Compatibility
| Engine | Supported | Notes |
|---|---|---|
| Chrome | Yes | — |
| Firefox | Yes | — |
| Safari | Yes | — |
| Edge | Yes | — |
| Node.js | Yes | — |