{"record":{"id":"5c87c92cb2a1e2b1","repo":"unclecode/crawl4ai","slug":"invalid-parameter-s-for-klass-name-invali","errorCode":null,"errorMessage":"Invalid parameter(s) for {klass.__name__}: {invalid}","messagePattern":"Invalid parameter\\(s\\) for (.+?): (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"crawl4ai/async_configs.py","lineNumber":87,"sourceCode":"                    kwargs[key] = copy.deepcopy(value)\n        original_init(self, *args, **kwargs)\n\n    cls.__init__ = wrapped_init\n    cls._user_defaults = {}\n\n    @classmethod\n    def set_defaults(klass, **kwargs):\n        \"\"\"Set class-level default overrides for new instances.\n\n        Args:\n            **kwargs: Parameter names and their default values.\n\n        Raises:\n            ValueError: If any key is not a valid ``__init__`` parameter.\n        \"\"\"\n        invalid = set(kwargs) - valid_params\n        if invalid:\n            raise ValueError(\n                f\"Invalid parameter(s) for {klass.__name__}: {invalid}\"\n            )\n        for k, v in kwargs.items():\n            klass._user_defaults[k] = copy.deepcopy(v)\n\n    @classmethod\n    def get_defaults(klass):\n        \"\"\"Return a deep copy of the current class-level defaults.\"\"\"\n        return copy.deepcopy(klass._user_defaults)\n\n    @classmethod\n    def reset_defaults(klass, *names):\n        \"\"\"Clear class-level defaults.\n\n        With no arguments, removes all overrides.\n        With arguments, removes only the named overrides.\n        \"\"\"\n        if names:","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/crawl4ai/async_configs.py#L69-L105","documentation":"EgressBlocked ('URL blocked') from assert_host_allowed when DNS returns an answer whose IP is non-globally-routable — loopback, private (RFC1918), link-local, and embedded IPv4 transition forms all count. The rule is strict: if ANY resolved address is forbidden, the whole host is rejected, closing the DNS-rebinding window where a name resolves to both a public and a private IP.","triggerScenarios":"Crawling a public-looking domain whose DNS includes an A/AAAA record for 10.x/172.16-31.x/192.168.x/127.x/169.254.x or an IPv6 with an embedded private v4 form. Multi-answer DNS (round-robin with one internal record) also triggers it.","commonSituations":"Split-horizon DNS where the same name resolves internally and externally; a domain temporarily publishing an internal IP; trying to reach cloud-metadata-adjacent addresses via a name; test domains pointing at 127.0.0.1.","solutions":["Use a hostname whose DNS answers are all globally routable (check: dig +short <host> from the container)","If you own the DNS zone, remove the private/loopback records from the public-facing name","For intentionally internal targets, use an ALLOW_INTERNAL deployment explicitly scoped for that job"],"exampleFix":"# diagnose from inside the container\n# dig +short risky.example.com\n# 203.0.113.10\n# 10.0.0.5      <- this answer triggers EgressBlocked\n# fix: publish only public records for that name, then retry the crawl","handlingStrategy":"validation","validationCode":"import socket, ipaddress\ndef all_answers_global(host: str) -> bool:\n    try:\n        answers = socket.getaddrinfo(host, 443, proto=socket.IPPROTO_TCP)\n    except socket.gaierror:\n        return False\n    return all(ipaddress.ip_address(a[4][0]).is_global for a in answers)","typeGuard":null,"tryCatchPattern":"from egress_broker import EgressBlocked\ntry:\n    assert_host_allowed(host, port)\nexcept EgressBlocked as e:\n    if not all_answers_global(host):\n        flag_domain_for_dns_review(host)  # split-horizon / rebinding suspect\n    raise","preventionTips":["Pre-check DNS answers for globality before crawling user-supplied domains","Watch for split-horizon DNS on your own domains; publish only public records publicly","Remember ANY internal answer blocks the host — one bad record is enough"],"tags":["ssrf-protection","egress","dns-rebinding","private-ip"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}