pydantic/pydantic · error · PydanticCustomError

ip_any_interface

ip_any_interface

Error message

value is not a valid IPv4 or IPv6 interface

What it means

IPvAnyInterface tries IPv4Interface(value) then IPv6Interface(value); on both failing it raises PydanticCustomError code 'ip_any_interface'. An 'interface' is an address plus a prefix length (e.g. 192.168.1.1/24), identifying a host on a subnet.

Source

Thrown at pydantic/networks.py:1240

        def _validate(cls, input_value: Any, /) -> IPvAnyAddressType:
            return cls(input_value)  # type: ignore[return-value]

    class IPvAnyInterface:
        """Validate an IPv4 or IPv6 interface."""

        __slots__ = ()

        def __new__(cls, value: NetworkType) -> IPvAnyInterfaceType:
            """Validate an IPv4 or IPv6 interface."""
            try:
                return IPv4Interface(value)
            except ValueError:
                pass

            try:
                return IPv6Interface(value)
            except ValueError:
                raise PydanticCustomError('ip_any_interface', 'value is not a valid IPv4 or IPv6 interface')

        @classmethod
        def __get_pydantic_json_schema__(
            cls, core_schema: core_schema.CoreSchema, handler: _schema_generation_shared.GetJsonSchemaHandler
        ) -> JsonSchemaValue:
            field_schema = {}
            field_schema.update(type='string', format='ipvanyinterface')
            return field_schema

        @classmethod
        def __get_pydantic_core_schema__(
            cls,
            _source: type[Any],
            _handler: GetCoreSchemaHandler,
        ) -> core_schema.CoreSchema:
            return core_schema.no_info_plain_validator_function(
                cls._validate, serialization=core_schema.to_string_ser_schema()
            )

View on GitHub (pinned to 2e5f0e2b42)

Solutions

  1. Provide address plus prefix: '192.168.1.1/24' or '2001:db8::1/64'.
  2. If only a bare address is expected, switch the field to IPvAnyAddress.
  3. If you want the network only, use IPvAnyNetwork.

Example fix

# before
class M(BaseModel):
    iface: IPvAnyInterface
M(iface='10.0.0.1')
# after
M(iface='10.0.0.1/24')
Defensive patterns

Strategy: validation

Validate before calling

import ipaddress
def parse_ip_any_interface(value):
    try:
        return ipaddress.ip_interface(value)
    except ValueError:
        raise ValueError(f'{value!r} is not a valid IPv4 or IPv6 interface')

Type guard

import ipaddress
def is_ip_interface(value) -> bool:
    try:
        ipaddress.ip_interface(value)
        return True
    except ValueError:
        return False

Try / catch

from pydantic import ValidationError
try:
    M(iface=user_input)
except ValidationError as e:
    if any(err['type'] == 'ip_any_interface' for err in e.errors()):
        ...

Prevention

When it happens

Trigger: Passing a plain address without prefix ('192.168.1.1'), a hostname, a URL, or a malformed CIDR to a field typed IPvAnyInterface.

Common situations: Confusing interface notation with a bare address or a network; omitting the /prefix; user input that is a hostname rather than an IP+mask.

Related errors


AI-assisted analysis of pydantic/pydantic@2e5f0e2b42 (2026-08-04). Data as JSON: /data/errors/0caeb30052bb3769.json. Report an issue: GitHub.