conductor-oss/conductor · critical · DocumentAccessDeniedException

Access denied: loopback address is blocked (host resolves to

Error message

Access denied: loopback address is blocked (host resolves to {address})

What it means

Thrown by DocumentAccessPolicy.checkResolvedAddress when the resolved InetAddress.isLoopbackAddress() is true (127.0.0.0/8, ::1). Like error 151 it runs after DNS normalization to defeat encoded/obfuscated loopback forms and DNS rebinding. The policy intentionally blocks loopback from document loaders so a loader cannot reach services bound to localhost on the Conductor host. DocumentAccessDeniedException (SecurityException).

Source

Thrown at ai/src/main/java/org/conductoross/conductor/ai/document/DocumentAccessPolicy.java:364

        // rebinding because InetAddress.getByName normalizes all representations.
        checkResolvedAddress(host);
    }

    /**
     * Resolves the host to an IP address and blocks link-local (169.254.0.0/16) and other dangerous
     * ranges that are commonly used for SSRF against cloud metadata services.
     */
    private void checkResolvedAddress(String host) {
        try {
            InetAddress addr = InetAddress.getByName(host);
            if (addr.isLinkLocalAddress()) {
                throw new DocumentAccessDeniedException(
                        "Access denied: link-local address range is blocked (host resolves to "
                                + addr.getHostAddress()
                                + ")");
            }
            if (addr.isLoopbackAddress()) {
                throw new DocumentAccessDeniedException(
                        "Access denied: loopback address is blocked (host resolves to "
                                + addr.getHostAddress()
                                + ")");
            }
        } catch (DocumentAccessDeniedException e) {
            throw e;
        } catch (Exception e) {
            // DNS resolution failure — allow the request to proceed and fail naturally
            log.debug(
                    "Could not resolve host '{}' for access policy check: {}",
                    host,
                    e.getMessage());
        }
    }

    private void checkPathTraversal(String normalizedPath) {
        if (normalizedPath.contains("/../")
                || normalizedPath.endsWith("/..")

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Access the resource via its real external/network address rather than localhost.
  2. If you need local content, load it as a file under an allowed directory instead of over HTTP.
  3. Treat loopback-targeting URLs from untrusted input as SSRF attempts.

Example fix

// before
loader.download("http://localhost:8080/report")
// after — use the routable address
loader.download("https://reports.example.com/report")
Defensive patterns

Strategy: validation

Validate before calling

// Resolve and reject loopback before the loader call
java.net.InetAddress a = java.net.InetAddress.getByName(host);
if (a.isLoopbackAddress()) {
    throw new SecurityException("Refusing loopback host: " + host + " -> " + a.getHostAddress());
}

Try / catch

try {
    loader.download(url);
} catch (SecurityException e) {
    // loopback is intentionally blocked — use the routable address
    throw new SecurityException("Blocked loopback resolution for: " + url, e);
}

Prevention

When it happens

Trigger: An HTTP loader is pointed at localhost/127.0.0.1/::1 or a hostname that resolves to a loopback address — e.g. http://localhost:8080/admin or a rebinding domain flipping to 127.0.0.1.

Common situations: Trying to read a local dev server through the document loader; SSRF probing for localhost-only admin endpoints; a service whose public DNS resolves to 127.0.0.1 (misconfiguration).

Understand the failure class

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/6cfde2df3e0c0961. Report an issue: GitHub.