{"record":{"id":"8db9e273c8907399","repo":"AUTOMATIC1111/stable-diffusion-webui","slug":"request-to-local-resource-not-allowed","errorCode":null,"errorMessage":"Request to local resource not allowed","messagePattern":"Request to local resource not allowed","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"modules/api/api.py","lineNumber":83,"sourceCode":"        domain_name = parsed_url.netloc\n        host = socket.gethostbyname_ex(domain_name)\n        for ip in host[2]:\n            ip_addr = ipaddress.ip_address(ip)\n            if not ip_addr.is_global:\n                return False\n    except Exception:\n        return False\n\n    return True\n\n\ndef decode_base64_to_image(encoding):\n    if encoding.startswith(\"http://\") or encoding.startswith(\"https://\"):\n        if not opts.api_enable_requests:\n            raise HTTPException(status_code=500, detail=\"Requests not allowed\")\n\n        if opts.api_forbid_local_requests and not verify_url(encoding):\n            raise HTTPException(status_code=500, detail=\"Request to local resource not allowed\")\n\n        headers = {'user-agent': opts.api_useragent} if opts.api_useragent else {}\n        response = requests.get(encoding, timeout=30, headers=headers)\n        try:\n            image = images.read(BytesIO(response.content))\n            return image\n        except Exception as e:\n            raise HTTPException(status_code=500, detail=\"Invalid image url\") from e\n\n    if encoding.startswith(\"data:image/\"):\n        encoding = encoding.split(\";\")[1].split(\",\")[1]\n    try:\n        image = images.read(BytesIO(base64.b64decode(encoding)))\n        return image\n    except Exception as e:\n        raise HTTPException(status_code=500, detail=\"Invalid encoded image\") from e\n\n","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/82a973c04367123ae98bd9abdf80d9eda9b910e2/modules/api/api.py#L65-L101","documentation":"HTTP 500 raised by decode_base64_to_image when URL inputs are allowed (api_enable_requests on) but api_forbid_local_requests is also enabled and verify_url() resolved the URL to a non-global (private/loopback/link-local) IP or DNS resolution failed (the except path also returns False). It is the SSRF mitigation that stops API clients from making the server fetch http://169.254.169.254/, http://localhost/..., 10.x, 192.168.x, etc.","triggerScenarios":"img2img or interrogate request with image URL pointing at localhost, 127.0.0.1, a private LAN address, a .local hostname, or a domain whose DNS fails to resolve (any exception in ip_address/resolution counts as not verified); requires api_enable_requests=true and api_forbid_local_requests=true on the server.","commonSituations":"Docker deployments where the client references the container's own or sibling service by internal hostname; clients pointing at localhost image servers; hostnames that intermittently fail DNS, which the except swallows into 'not allowed'.","solutions":["Serve the image from a globally reachable URL, or send the bytes as base64/data URI instead","If this is deliberate and trusted (single-user LAN setup), disable Settings -> API -> 'Forbid inputs pointing to local resources' (api_forbid_local_requests)","Ensure the URL's DNS resolves publicly; a resolution failure is treated the same as a local address"],"exampleFix":"# before (server-side fetch of LAN resource)\njson={'init_images':['http://192.168.1.10:9000/photo.png']}\n\n# after\nb64 = base64.b64encode(open('photo.png','rb').read()).decode()\njson={'init_images':[b64]}","handlingStrategy":"validation","validationCode":"import ipaddress, socket\nfrom urllib.parse import urlparse\ndef url_is_public(u: str) -> bool:\n    try:\n        host = urlparse(u).hostname\n        ip = ipaddress.ip_address(socket.gethostbyname(host))\n        return ip.is_global\n    except Exception:\n        return False\n# before sending a URL payload when forbid_local is on:\nif opts.get('api_forbid_local_requests') and not all(url_is_public(u) for u in urls):\n    payload['init_images'] = [b64_from_url(u) for u in urls]","typeGuard":"def is_safe_remote_url(u: str) -> bool:\n    return url_is_public(u)","tryCatchPattern":"if resp.status_code == 500 and 'local resource' in resp.json()['detail']:\n    payload['init_images'] = [b64_from_url(u) for u in payload['init_images']]\n    resp = requests.post(url, json=payload, auth=auth)","preventionTips":["Never point the API at localhost/LAN/169.254.x.x URLs unless you administer the server","Mirror verify_url() client-side before sending","Prefer base64 for anything served near the server"],"tags":["api","security","ssrf","network","http-500","stable-diffusion-webui"],"backgroundTag":null,"analyzedSha":"82a973c04367123ae98bd9abdf80d9eda9b910e2","analyzedAt":"2026-08-14T16:46:43.225Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}