{"record":{"id":"01ae14d7a4fa6298","repo":"spring-projects/spring-ai","slug":"failed-to-cache-the-resource","errorCode":null,"errorMessage":"Failed to cache the resource: ","messagePattern":"Failed to cache the resource: ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"models/spring-ai-transformers/src/main/java/org/springframework/ai/transformers/ResourceCacheService.java","lineNumber":128,"sourceCode":"\t * the excluded schema list the original resource is returned.\n\t */\n\tpublic Resource getCachedResource(Resource originalResource) {\n\t\ttry {\n\t\t\tif (this.excludedUriSchemas.contains(originalResource.getURI().getScheme())) {\n\t\t\t\tlogger.info(\"The \" + originalResource.toString() + \" resource with URI schema [\"\n\t\t\t\t\t\t+ originalResource.getURI().getScheme() + \"] is excluded from caching\");\n\t\t\t\treturn originalResource;\n\t\t\t}\n\n\t\t\tFile cachedFile = getCachedFile(originalResource);\n\t\t\tif (!cachedFile.exists()) {\n\t\t\t\tFileCopyUtils.copy(StreamUtils.copyToByteArray(originalResource.getInputStream()), cachedFile);\n\t\t\t\tlogger.info(\"Caching the \" + originalResource.toString() + \" resource to: \" + cachedFile);\n\t\t\t}\n\t\t\treturn new FileUrlResource(cachedFile.getAbsolutePath());\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new IllegalStateException(\"Failed to cache the resource: \" + originalResource.getDescription(), e);\n\t\t}\n\t}\n\n\tprivate File getCachedFile(Resource originalResource) throws IOException {\n\t\tvar resourceParentFolder = new File(this.cacheDirectory,\n\t\t\t\tUUID.nameUUIDFromBytes(pathWithoutLastSegment(originalResource.getURI())).toString());\n\t\tresourceParentFolder.mkdirs();\n\t\tString newFileName = getCacheName(originalResource);\n\t\tFile cachedFile = new File(resourceParentFolder, newFileName);\n\t\tString canonicalCache = this.cacheDirectory.getCanonicalPath() + File.separator;\n\t\tif (!cachedFile.getCanonicalPath().startsWith(canonicalCache)) {\n\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\"Resource URI resolves outside the cache directory: \" + originalResource.getDescription());\n\t\t}\n\t\treturn cachedFile;\n\t}\n\n\tprivate byte[] pathWithoutLastSegment(URI uri) {","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/spring-projects/spring-ai/blob/98a7beda4f29d80a71c5837eb4053b03a93a46f7/models/spring-ai-transformers/src/main/java/org/springframework/ai/transformers/ResourceCacheService.java#L110-L146","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nResource r = new UrlResource(\"https://huggingface.co/model/onnx/model.onnx\"); // unreachable\n// after\n// verify URL reachability & cache dir permissions, then:\nFile cached = resourceCacheService.getCachedResource(new UrlResource(validUrl));","handlingStrategy":"try-catch","validationCode":"// pre-check remote availability\nHttpURLConnection c = (HttpURLConnection) new URL(resourceUrl).openConnection();\nc.setRequestMethod(\"HEAD\");\nif (c.getResponseCode() != 200) throw new IllegalStateException(\"Resource unavailable: \" + c.getResponseCode());","typeGuard":null,"tryCatchPattern":"try {\n    File cached = resourceCacheService.getCachedResource(resource);\n} catch (IllegalStateException e) {\n    logger.error(\"Caching failed for {} cause: {}\", e.getMessage(), e.getCause(), e);\n    throw e;\n}","preventionTips":["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."],"tags":["io","cache","network","resource"],"backgroundTag":"http-request-failed","analyzedSha":"98a7beda4f29d80a71c5837eb4053b03a93a46f7","analyzedAt":"2026-09-11T14:15:49.441Z","contentChangedAt":"2026-09-11T14:15:49.441Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}