data validation_error ai_generated true

JSON Schema validation fails: format 'uri' rejects valid URIs with IP addresses or unusual schemes

ID: data/json-schema-format-uri-referencing

Also available as: JSON · Markdown · 中文
80%Fix Rate
82%Confidence
1Evidence
2023-06-20First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
jsonschema 4.17.3 active
ajv 8.12.0 active
json-schema-validator 4.0.1 active

Root Cause

JSON Schema's built-in 'uri' format validator in some libraries (e.g., Python's jsonschema) uses strict RFC 3986 parsing that may reject valid URIs with IPv6 literals or custom schemes like 'dns://'.

generic

中文

某些库(如 Python 的 jsonschema)中 JSON Schema 内置的 'uri' 格式验证器使用严格的 RFC 3986 解析,可能拒绝包含 IPv6 字面量或自定义方案(如 'dns://')的合法 URI。

Official Documentation

https://json-schema.org/understanding-json-schema/reference/string.html#built-in-formats

Workarounds

  1. 85% success Use a custom format checker with relaxed URI validation: from jsonschema import validators; from rfc3986_validator import validate_rfc3986; def custom_uri(instance): return validate_rfc3986(instance, require_scheme=True, allow_relative=False); validator = validators.validate(..., format_checker=validators.Draft7Validator.FORMAT_CHECKER.replaces('uri', custom_uri))
    Use a custom format checker with relaxed URI validation: from jsonschema import validators; from rfc3986_validator import validate_rfc3986; def custom_uri(instance): return validate_rfc3986(instance, require_scheme=True, allow_relative=False); validator = validators.validate(..., format_checker=validators.Draft7Validator.FORMAT_CHECKER.replaces('uri', custom_uri))
  2. 75% success Change schema to use pattern validation instead of format: '"pattern": "^[a-zA-Z][a-zA-Z0-9+.-]*://.*$"'. This is more portable across validators.
    Change schema to use pattern validation instead of format: '"pattern": "^[a-zA-Z][a-zA-Z0-9+.-]*://.*$"'. This is more portable across validators.

中文步骤

  1. Use a custom format checker with relaxed URI validation: from jsonschema import validators; from rfc3986_validator import validate_rfc3986; def custom_uri(instance): return validate_rfc3986(instance, require_scheme=True, allow_relative=False); validator = validators.validate(..., format_checker=validators.Draft7Validator.FORMAT_CHECKER.replaces('uri', custom_uri))
  2. Change schema to use pattern validation instead of format: '"pattern": "^[a-zA-Z][a-zA-Z0-9+.-]*://.*$"'. This is more portable across validators.

Dead Ends

Common approaches that don't work:

  1. 60% fail

    Completely bypasses URI validation, allowing invalid URIs through and defeating the purpose of schema validation.

  2. 55% fail

    uri-reference is even more permissive and may not catch intended validation issues, plus it's not supported by all validators.