spring-projects/spring-ai · error · IllegalStateException
Failed to cache the resource:
Error message
Failed to cache the resource:
What it means
getCachedResource downloads the given resource and copies it into the local cache directory, returning a FileUrlResource pointing at the cached copy. Any failure during the whole caching process (network fetch, stream read, file copy, directory creation) is caught and rethrown as IllegalStateException("Failed to cache the resource: " + description, e), preserving the cause.
Source
Thrown at models/spring-ai-transformers/src/main/java/org/springframework/ai/transformers/ResourceCacheService.java:128
* the excluded schema list the original resource is returned.
*/
public Resource getCachedResource(Resource originalResource) {
try {
if (this.excludedUriSchemas.contains(originalResource.getURI().getScheme())) {
logger.info("The " + originalResource.toString() + " resource with URI schema ["
+ originalResource.getURI().getScheme() + "] is excluded from caching");
return originalResource;
}
File cachedFile = getCachedFile(originalResource);
if (!cachedFile.exists()) {
FileCopyUtils.copy(StreamUtils.copyToByteArray(originalResource.getInputStream()), cachedFile);
logger.info("Caching the " + originalResource.toString() + " resource to: " + cachedFile);
}
return new FileUrlResource(cachedFile.getAbsolutePath());
}
catch (Exception e) {
throw new IllegalStateException("Failed to cache the resource: " + originalResource.getDescription(), e);
}
}
private File getCachedFile(Resource originalResource) throws IOException {
var resourceParentFolder = new File(this.cacheDirectory,
UUID.nameUUIDFromBytes(pathWithoutLastSegment(originalResource.getURI())).toString());
resourceParentFolder.mkdirs();
String newFileName = getCacheName(originalResource);
File cachedFile = new File(resourceParentFolder, newFileName);
String canonicalCache = this.cacheDirectory.getCanonicalPath() + File.separator;
if (!cachedFile.getCanonicalPath().startsWith(canonicalCache)) {
throw new IllegalArgumentException(
"Resource URI resolves outside the cache directory: " + originalResource.getDescription());
}
return cachedFile;
}
private byte[] pathWithoutLastSegment(URI uri) {View on GitHub (pinned to 98a7beda4f)
Solutions
- Inspect the wrapped cause (e.getCause()) to see whether it is a network fetch failure or a local write failure.
- Verify the resource URL is reachable from the runtime environment (curl the URL, check proxies/firewall).
- Make the configured cache directory writable and ensure sufficient disk space.
- Pre-populate the cache directory manually so downloads are not needed at startup.
Example fix
// before
Resource r = new UrlResource("https://huggingface.co/model/onnx/model.onnx"); // unreachable
// after
// verify URL reachability & cache dir permissions, then:
File cached = resourceCacheService.getCachedResource(new UrlResource(validUrl)); Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check remote availability
HttpURLConnection c = (HttpURLConnection) new URL(resourceUrl).openConnection();
c.setRequestMethod("HEAD");
if (c.getResponseCode() != 200) throw new IllegalStateException("Resource unavailable: " + c.getResponseCode()); Try / catch
try {
File cached = resourceCacheService.getCachedResource(resource);
} catch (IllegalStateException e) {
logger.error("Caching failed for {} cause: {}", e.getMessage(), e.getCause(), e);
throw e;
} Prevention
- Verify resource URLs are reachable from the runtime (proxies, firewall, signed-URL expiry).
- Keep the cache directory writable and sized for the models you load.
- Inspect e.getCause() to distinguish network vs. local write failures.
When it happens
Trigger: Calling getCachedResource with a Resource whose InputStream cannot be read (remote 404/403, DNS failure) or whose bytes cannot be written to the cache file (read-only cache dir, disk full).
Common situations: Hosting models on an internal URL that is unreachable from the runtime; expired signed URLs; missing permissions on the cache volume in Kubernetes/containers; proxy/firewall blocking outbound Hugging Face downloads.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Request failed
- Failed to write request body
- Failed to read audio speech response
- Failed to read resource:
- Request failed
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/01ae14d7a4fa6298.
Report an issue: GitHub.