C#
IP validation
IPv4
IPv6
programming tutorial

How to determine if a string is a valid IPv4 or IPv6 address in C?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, the simplest and most reliable way to validate an IPv4 or IPv6 string is IPAddress.TryParse. It understands standard textual IP formats, avoids exception-driven control flow, and lets you distinguish IPv4 from IPv6 by checking the resulting AddressFamily.

Use IPAddress.TryParse First

The core API is in System.Net.

csharp
1using System;
2using System.Net;
3
4string input = "2001:db8::1";
5
6bool ok = IPAddress.TryParse(input, out IPAddress? address);
7
8Console.WriteLine(ok);
9Console.WriteLine(address);

If the string is a valid IP literal, TryParse returns true and gives you an IPAddress instance. If it is invalid, it returns false without throwing.

That makes it the right default choice for validation code.

Distinguish IPv4 from IPv6

If you want to know not just whether the string is valid, but which protocol version it represents, inspect AddressFamily.

csharp
1using System;
2using System.Net;
3using System.Net.Sockets;
4
5static string DescribeIp(string input)
6{
7    if (!IPAddress.TryParse(input, out IPAddress? address))
8        return "Invalid";
9
10    return address.AddressFamily switch
11    {
12        AddressFamily.InterNetwork => "Valid IPv4",
13        AddressFamily.InterNetworkV6 => "Valid IPv6",
14        _ => "Valid IP of another family"
15    };
16}
17
18Console.WriteLine(DescribeIp("192.168.1.20"));
19Console.WriteLine(DescribeIp("2001:db8::1"));
20Console.WriteLine(DescribeIp("not-an-ip"));

This is the usual answer when the requirement is "accept both, but tell me which one it is."

Why TryParse Is Better Than Parse

IPAddress.Parse also works, but it throws if the input is invalid.

csharp
1using System;
2using System.Net;
3
4try
5{
6    var address = IPAddress.Parse("bad-value");
7    Console.WriteLine(address);
8}
9catch (FormatException)
10{
11    Console.WriteLine("Invalid IP address");
12}

For validation, TryParse is preferable because invalid input is expected input, not exceptional input.

A Reusable Validator

If you want a small helper API, you can wrap the logic cleanly.

csharp
1using System.Net;
2using System.Net.Sockets;
3
4public static class IpValidation
5{
6    public static bool IsIpv4(string input) =>
7        IPAddress.TryParse(input, out var address) &&
8        address.AddressFamily == AddressFamily.InterNetwork;
9
10    public static bool IsIpv6(string input) =>
11        IPAddress.TryParse(input, out var address) &&
12        address.AddressFamily == AddressFamily.InterNetworkV6;
13}

Usage:

csharp
Console.WriteLine(IpValidation.IsIpv4("127.0.0.1"));
Console.WriteLine(IpValidation.IsIpv6("::1"));
Console.WriteLine(IpValidation.IsIpv4("::1"));

This is easy to test and avoids duplicating the parsing logic across the codebase.

About IPv6 Variants

One reason it is a mistake to use a hand-written regex for this job is that valid IPv6 text has several legal representations, including compressed forms.

These can all be valid:

  • '2001:0db8:0000:0000:0000:0000:0000:0001'
  • '2001:db8::1'
  • '::1'

The built-in parser already handles those rules correctly. A custom regex often gets them wrong or becomes much harder to maintain than the built-in API.

Be Careful About What You Mean by “Valid”

IPAddress.TryParse answers whether the text is a syntactically valid IP address literal. It does not answer:

  • whether the host exists
  • whether the address is reachable
  • whether the address is public or private
  • whether the address is appropriate for your application rule set

For example, 127.0.0.1 is valid IPv4 text, but that does not mean it is acceptable as a remote client address in every context.

So validation often has two stages:

  1. syntactic parsing
  2. application-specific acceptance rules

Normalizing the Result

If you want a canonical string representation after validation, use the parsed object’s ToString().

csharp
1using System;
2using System.Net;
3
4if (IPAddress.TryParse("2001:0db8:0000:0000:0000:0000:0000:0001", out var address))
5{
6    Console.WriteLine(address.ToString());
7}

For IPv6, the output may be compressed to a shorter standard form such as 2001:db8::1.

That can be useful if you want normalized storage or comparison.

Common Pitfalls

One common mistake is using regex for IP validation when the framework already provides a tested parser that handles IPv4 and IPv6 formats correctly.

Another issue is treating Parse as a validator. It works, but TryParse is usually the better API because invalid input should not need exception handling.

Developers also sometimes forget to check AddressFamily, which means they validate “some IP” when the actual requirement was “specifically IPv4” or “specifically IPv6”.

Finally, a syntactically valid IP string is not the same as an acceptable business-level value. Apply separate rules if you need to reject loopback, multicast, private, or link-local addresses.

Summary

  • Use IPAddress.TryParse to validate IP strings in C#.
  • Check AddressFamily to distinguish IPv4 from IPv6.
  • Prefer TryParse over Parse for ordinary validation.
  • Avoid regex for this unless you have a very specialized reason.
  • Remember that syntactic validity is different from application-level acceptability.

Course illustration
Course illustration