spring-projects/spring-ai · error · java.lang.SecurityException
Failed to resolve host:
Error message
Failed to resolve host:
What it means
When URLValidator.assertNoInternalAddress cannot resolve the host at all, InetAddress.getAllByName throws UnknownHostException, which is translated into this SecurityException (with the original exception attached) so it flows through Spring RestClient as a RuntimeException instead of being wrapped in ResourceAccessException. It signals the strict URL check could not complete because DNS resolution failed.
Source
Thrown at models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/URLValidator.java:143
* {@link SecurityException} if any resolve to a loopback, link-local, site-local, or
* wildcard address. Protects against SSRF via internal network access (including IPv6
* equivalents) and limits exposure from DNS rebinding by checking all returned
* addresses.
* @param host the hostname to check
* @throws SecurityException if the host resolves to a blocked internal address or
* cannot be resolved
*/
public static void assertNoInternalAddress(String host) {
try {
for (InetAddress address : InetAddress.getAllByName(host)) {
if (isBlockedAddress(address)) {
throw new SecurityException("URL host '" + host + "' resolves to a blocked internal address: "
+ address.getHostAddress());
}
}
}
catch (UnknownHostException e) {
throw new SecurityException("Failed to resolve host: " + host, e);
}
}
/**
* Returns {@code true} if the given address is a loopback, link-local, site-local, or
* wildcard address. Covers both IPv4 and IPv6 private/internal ranges.
* @param address the address to test
* @return {@code true} if the address should be blocked
*/
public static boolean isBlockedAddress(InetAddress address) {
return address.isLoopbackAddress() || address.isLinkLocalAddress() || address.isSiteLocalAddress()
|| address.isAnyLocalAddress();
}
/**
* Attempts to fix common URL issues Adds protocol if missing, removes extra spaces
*/
public static @Nullable String normalizeURL(@Nullable String urlString) {View on GitHub (pinned to 98a7beda4f)
Solutions
- Verify the hostname is spelled correctly and is publicly resolvable (dig/nslookup/ping it from the runtime environment).
- Fix DNS in the runtime environment (resolv.conf, CoreDNS, VPC DNS settings) if legitimate public hosts fail to resolve.
- Replace internal-only hostnames with public CDN/S3 endpoints, or fetch the media yourself and pass bytes inline.
- Catch SecurityException and surface a 'could not resolve media host' validation error to the caller; optionally retry on transient DNS failures.
Example fix
// before
Media media = new Media(MimeTypeUtils.IMAGE_JPEG, new URL("https://medai.example.com/cat.jpg")); // typo: medai
// after
Media media = new Media(MimeTypeUtils.IMAGE_JPEG, new URL("https://media.example.com/cat.jpg")); Defensive patterns
Strategy: try-catch
Validate before calling
// Java: attempt resolution yourself first and fail fast with a clear message
try {
InetAddress.getAllByName(mediaUrl.getHost());
} catch (UnknownHostException e) {
throw new IllegalArgumentException("Media URL host cannot be resolved: " + mediaUrl.getHost(), e);
} Try / catch
try {
model.call(prompt);
} catch (SecurityException e) {
if (e.getMessage().startsWith("Failed to resolve host")) {
// report DNS failure to the user; optionally retry once for transient DNS issues
} else { throw e; }
} Prevention
- Verify hostnames resolve (dig/nslookup) from the same environment that runs the model call.
- Check DNS configuration in containers/Kubernetes (resolv.conf, CoreDNS) before deploying.
- Validate URL syntax and hostname format at your API boundary.
- Apply a small retry with backoff for transient DNS failures, but never for blocked/internal-address rejections.
When it happens
Trigger: isValidURLStrict → assertNoInternalAddress with a hostname that DNS cannot resolve: typo'd domains, unregistered hosts, names only resolvable on an internal DNS server the runtime cannot reach, or environments with broken/no DNS.
Common situations: Typo in the media URL host (e.g. .con instead of .com); using a corporate-internal hostname from a network without the internal DNS; running in a container/pod with misconfigured resolv.conf or blocked DNS egress; transient DNS resolver outages.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- URL host '' resolves to a blocked internal address:
- URL is not valid under strict validation rules:
- Host '' resolves to a blocked internal address:
- Unsupported URL protocol:
- Host '' is not in the allowed hosts list. Configure MediaFet
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/7716c14ee16b862d.
Report an issue: GitHub.