spring-projects/spring-ai · error · java.lang.SecurityException

Media URL response exceeds maximum allowed size of bytes:

Error message

Media URL response exceeds maximum allowed size of  bytes: 

What it means

MediaFetcher.fetch() checks the HTTP Content-Length header before reading the body and throws SecurityException if it exceeds DEFAULT_MAX_FETCH_SIZE_BYTES, protecting against downloading oversized media. A size limit is also enforced while streaming the body via readWithSizeLimit, guarding responses that lie about or omit Content-Length.

Source

Thrown at models/spring-ai-bedrock-converse/src/main/java/org/springframework/ai/bedrock/converse/api/MediaFetcher.java:154

	 * @param uri the URI to fetch
	 * @return the response body as a byte array
	 * @throws SecurityException if the response exceeds
	 * {@link #DEFAULT_MAX_FETCH_SIZE_BYTES} or the host resolves to a blocked internal
	 * address
	 * @throws org.springframework.web.client.RestClientException on HTTP or I/O errors
	 */
	public byte[] fetch(URI uri) {
		if (!this.allowedHosts.isEmpty()) {
			String host = uri.getHost();
			if (!isHostAllowed(host)) {
				throw new SecurityException("Host '" + host
						+ "' is not in the allowed hosts list. Configure MediaFetcher with the appropriate allowed hosts.");
			}
		}
		return this.restClient.get().uri(uri).exchange((request, response) -> {
			long contentLength = response.getHeaders().getContentLength();
			if (contentLength > DEFAULT_MAX_FETCH_SIZE_BYTES) {
				throw new SecurityException("Media URL response exceeds maximum allowed size of "
						+ DEFAULT_MAX_FETCH_SIZE_BYTES + " bytes: " + uri);
			}
			try (InputStream body = response.getBody()) {
				return readWithSizeLimit(body, DEFAULT_MAX_FETCH_SIZE_BYTES);
			}
		}, true);
	}

	/**
	 * Returns {@code true} if {@code host} is permitted by the allowlist. An entry that
	 * starts with {@code *.} is treated as a suffix wildcard matching any subdomain (e.g.
	 * {@code *.example.com} matches {@code img.example.com} but not {@code example.com}
	 * itself).
	 */
	private boolean isHostAllowed(String host) {
		if (host == null) {
			return false;
		}

View on GitHub (pinned to 98a7beda4f)

Solutions

  1. Reduce the media size or serve a compressed/smaller rendition.
  2. Increase the fetcher's max size limit if legitimate large media is expected.
  3. Ensure the URL points to the specific media asset, not a generic download.
  4. Pre-check size via a HEAD request if the caller wants to fail earlier.

Example fix

// before
byte[] data = mediaFetcher.fetch(new URI("https://cdn.example.com/huge-video.mp4")); // 200MB
// after
byte[] data = mediaFetcher.fetch(new URI("https://cdn.example.com/clip-5mb.mp4"));
Defensive patterns

Strategy: try-catch

Validate before calling

try (Response head = restClient.head()) {
    // check HEAD content-length against configured max before fetching
}

Try / catch

try {
    byte[] data = mediaFetcher.fetch(uri);
} catch (SecurityException e) {
    // oversized media: request a smaller rendition or skip
} catch (org.springframework.web.client.RestClientException e) {
    // HTTP/IO failure during streaming
}

Prevention

When it happens

Trigger: Fetching a media URI whose response declares Content-Length greater than the configured max fetch size, or whose streamed body exceeds the limit while being read.

Common situations: Pointing a media URL at a large video or archive file; a server serving a much larger file than expected; proxies that ignore range/size expectations.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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