spring-projects/spring-ai · error · SecurityException

URL is not valid under strict validation rules:

Error message

URL is not valid under strict validation rules: 

What it means

Thrown as SecurityException when a String media value fails URLValidator.isValidURLStrict in mapMediaToContentBlock. The library only accepts Strings that are either strictly valid http/https URLs or base64 data; anything failing strict URL validation is treated as base64, and if decode fails or validation is intended as URL this guard fires for rejected URLs (e.g. file://, ftp://, or otherwise non-conforming strings).

Source

Thrown at models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/BedrockProxyChatModel.java:550

			}
			else if (media.getData() instanceof String text) {

				if (text.startsWith("s3://")) {
					sourceBuilder.s3Location(S3Location.builder().uri(text).build()).build();
				}
				else if (text.startsWith("http://") || text.startsWith("https://")) {
					// Not base64
					if (URLValidator.isValidURLStrict(text)) {
						try {
							byte[] bytes = this.mediaFetcher.fetch(URI.create(text));
							sourceBuilder.bytes(SdkBytes.fromByteArrayUnsafe(bytes)).build();
						}
						catch (SecurityException | RestClientException e) {
							throw new RuntimeException("Failed to read media data from URL: " + text, e);
						}
					}
					else {
						throw new SecurityException("URL is not valid under strict validation rules: " + text);
					}
				}
				else {
					// Assume it's base64-encoded image data
					sourceBuilder.bytes(SdkBytes.fromByteArray(Base64.getDecoder().decode(text)));
				}
			}
			else if (media.getData() instanceof URL url) {

				try {
					String protocol = url.getProtocol();
					if (!"http".equalsIgnoreCase(protocol) && !"https".equalsIgnoreCase(protocol)) {
						throw new SecurityException("Unsupported URL protocol: " + protocol);
					}
					byte[] bytes = this.mediaFetcher.fetch(url.toURI());
					sourceBuilder.bytes(SdkBytes.fromByteArrayUnsafe(bytes)).build();
				}
				catch (SecurityException | RestClientException | URISyntaxException e) {

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Read the file yourself and pass base64-encoded bytes as the media data.
  2. Use a proper http(s):// URL that passes strict validation.
  3. Use a java.net.URL object via Media with URL data (which goes through the URL branch) only with http/https.
  4. If the string is meant to be base64, verify it decodes cleanly (no 'data:' prefix, no whitespace).

Example fix

// before
new Media(MimeTypeUtils.IMAGE_PNG, "file:///images/cat.png");
// after
byte[] bytes = Files.readAllBytes(Path.of("/images/cat.png"));
new Media(MimeTypeUtils.IMAGE_PNG, Base64.getEncoder().encodeToString(bytes));
Defensive patterns

Strategy: validation

Validate before calling

if (data != null && !URLValidator.isValidURLStrict(data) && !isBase64(data)) {
    throw new IllegalArgumentException("Media string is neither a valid strict URL nor base64");
}

Type guard

boolean isSafeMediaString(String s) {
    return s != null && (s.startsWith("https://") || s.startsWith("http://") || s.matches("[A-Za-z0-9+/=]+"));
}

Try / catch

try {
    model.call(prompt);
} catch (SecurityException e) {
    if (e.getMessage().startsWith("URL is not valid")) { /* use base64 instead */ }
    else throw e;
}

Prevention

When it happens

Trigger: Passing a Media with String data like 'file:///etc/passwd', 'ftp://host/img.png', or any string that strict validation rejects (missing scheme, disallowed characters). The else-branch throws this SecurityException before any base64 decoding is attempted.

Common situations: Developers try to load local files via file:// URLs into Bedrock prompts; others paste URLs with spaces or non-ASCII characters that fail strict validation; SSRF hardening intentionally rejects ftp/file schemes.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11). Data as JSON: /api/errors/3e9caa59dd02e799. Report an issue: GitHub.