IPv6 Address Regex
Validates a full or zero-compressed IPv6 address, including the double-colon (::) shorthand for one run of consecutive zero groups.
Regex Pattern
^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$Pattern Breakdown
Hover over a token to see what it does.
| Token | Meaning |
|---|---|
| ([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4} | Fully expanded form: exactly eight colon-separated groups of 1-4 hex digits |
| ([0-9a-fA-F]{1,4}:){1,7}: | One to seven groups followed by a trailing double colon, e.g. 2001:db8:: |
| ([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4} | Compressed form with the zero run before the final group |
| [0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6}) | A single leading group followed by a compressed run of up to six more groups |
| :((:[0-9a-fA-F]{1,4}){1,7}|:) | Address starting with :: followed by up to seven groups, or the all-zero address :: itself |
| [0-9a-fA-F]{1,4} | One hextet: one to four hexadecimal digits representing 16 bits |
| $ | Anchors the match to the end of the string |
Detailed Explanation
What it does
This pattern validates IPv6 addresses written in their standard colon-hexadecimal notation, supporting both the fully expanded eight-group form and the zero-compression shorthand (::) that collapses one run of consecutive all-zero groups. It correctly matches addresses like 2001:db8::1 as well as fe80::1ff:fe23:4567:890a.
Why it works
IPv6 addresses have eight 16-bit groups, but the :: shorthand can replace exactly one run of consecutive zero groups anywhere in the address, which means the number of explicit groups before and after :: can vary. The pattern handles this by enumerating every valid combination as a large alternation: the fully expanded 8-group form with no compression, and then one branch for each possible position of the :: (from compressing after the first group down to a single-group address), each branch counting how many groups appear before and after the double colon so the total never implicitly exceeds eight.
Common use cases
- Validating IPv6 input fields in network configuration UIs
- Filtering log files or configuration for lines containing IPv6 literals
- Distinguishing IPv6 addresses from IPv4 or hostnames in mixed data
- Pre-validating addresses before passing them to socket or DNS resolution APIs
Edge cases
- The all-zero address :: is valid shorthand for 0:0:0:0:0:0:0:0 and matches via the final alternation branch
- Addresses with only one :: compression are valid; a second :: like 2001:db8::85a3::8a2e is invalid and correctly rejected
- Leading zeros within a group are optional, so 2001:0db8::1 and 2001:db8::1 are both valid and match
- Groups longer than four hex digits, like 12345::, are correctly rejected
- This pattern does not natively support the embedded-IPv4 tail form (e.g. ::ffff:192.168.1.1) without an additional branch
Limitations
- Does not validate the embedded IPv4-mapped IPv6 notation (::ffff:a.b.c.d) out of the box
- Does not handle zone/scope IDs used for link-local addresses, such as fe80::1%eth0
- Extremely long due to enumerating every compression position, which makes it harder to read and maintain than the IPv4 pattern
- Cannot verify the address is actually assigned, routable, or reachable
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 | |||
| Pass | |||
| Pass |
Language Variants
Production-ready examples in 12 languages.
const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
console.log(ipv6Regex.test('2001:db8::1')); // trueCommon Mistakes
Assuming a simple pattern like [0-9a-fA-F:]+ is enough to validate IPv6, which accepts malformed strings like too many colons
Fix: Use the full alternation that enumerates valid group counts and :: compression positions, or better, use your language's built-in IP parser
Not accounting for the fact that :: can only appear once in a valid address
Fix: The alternation branches each assume a single :: position; reject any string containing two separate :: occurrences
Forgetting that IPv6 addresses can embed an IPv4 tail (::ffff:192.168.1.1) which this base pattern does not match
Fix: Add a dedicated alternation branch for the IPv4-mapped form if your application needs to accept it
Hand-rolling IPv6 validation in production code instead of using a standard library parser
Fix: Prefer built-in APIs like Python's ipaddress module, Go's net.ParseIP, or C#'s IPAddress.TryParse for authoritative validation, and reserve regex for quick client-side checks
Performance Notes
- This pattern is long because it enumerates every valid position of the :: compression as a separate alternation branch
- Alternation with overlapping prefixes (many branches starting with ([0-9a-fA-F]{1,4}:)) can cause the engine to backtrack across branches on non-matching input, though bounded by the fixed 8-group structure so it stays polynomial, not exponential
- For hot-path validation, prefer a native IP-parsing library over regex since it is both faster and more correct
- Anchoring with ^ and $ is essential given how many branches could otherwise partially match a longer invalid string
Browser Compatibility
| Engine | Supported | Notes |
|---|---|---|
| Chrome | Yes | — |
| Firefox | Yes | — |
| Safari | Yes | — |
| Edge | Yes | — |
| Node.js | Yes | — |