microsoft/aspire · error · FormatException

Only IPv4 CIDR notation is supported

Error message

Only IPv4 CIDR notation is supported: '{cidr}'.

What it means

ParseCidr only supports IPv4 addresses. After parsing the IP part of a CIDR string with IPAddress.Parse, it checks AddressFamily and throws FormatException if the address is not InterNetwork (IPv4). Subnet arithmetic in this allocator is implemented with 32-bit uint math, so IPv6 cannot be handled.

Solutions

  1. Use an IPv4 CIDR (e.g. '10.0.0.0/16') for the vnet address space
  2. Remove IPv6 address-space entries and rely on an IPv4 range for the deployment-script subnet
  3. Pre-validate address families with IPAddress.Parse and check AddressFamily.InterNetwork before calling

Example fix

// before
.WithAddressSpace("fd00:db8::/48") // IPv6-only vnet
// after
.WithAddressSpace("10.0.0.0/16") // IPv4 CIDR required
Defensive patterns

Strategy: validation

Validate before calling

bool IsIPv4Cidr(string cidr) =>
    System.Net.IPAddress.TryParse(cidr.Split('/')[0], out var ip)
    && ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork;

Try / catch

try { ParseCidr(cidr); }
catch (FormatException ex) when (ex.Message.Contains("IPv4")) { throw new NotSupportedException("IPv6 address spaces are not supported for subnet allocation", ex); }

Prevention

When it happens

Trigger: Passing an IPv6 CIDR such as 'fd00::/8' or '::1/128' into AllocateDeploymentScriptSubnet or any code path that calls ParseCidr.

Common situations: Using a dual-stack or IPv6-only vnet address space, copying an IPv6 prefix from Azure portal, or defaulting to IPv6 in custom networking configuration.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/37196f240df4c317. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Azure.Sql/SubnetAddressAllocator.cs:108

                return true;
            }
        }

        return false;
    }

    internal static (uint Start, uint End) ParseCidr(string cidr)
    {
        var parts = cidr.Split('/');
        if (parts.Length != 2 || !int.TryParse(parts[1], out var prefix) || prefix < 0 || prefix > 32)
        {
            throw new FormatException($"Invalid CIDR notation: '{cidr}'.");
        }

        var ip = IPAddress.Parse(parts[0]);
        if (ip.AddressFamily != AddressFamily.InterNetwork)
        {
            throw new FormatException($"Only IPv4 CIDR notation is supported: '{cidr}'.");
        }

        var bytes = ip.GetAddressBytes();
        var address = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);

        // Compute the network mask
        var mask = prefix == 0 ? 0u : uint.MaxValue << (32 - prefix);
        var networkAddress = address & mask;
        var broadcastAddress = networkAddress | ~mask;

        return (networkAddress, broadcastAddress);
    }

    private static string UintToIp(uint address)
    {
        return $"{(address >> 24) & 0xFF}.{(address >> 16) & 0xFF}.{(address >> 8) & 0xFF}.{address & 0xFF}";
    }
}

View on GitHub (pinned to 25830f84bd)