{"record":{"id":"fea8d4118bf1e0fe","repo":"conductor-oss/conductor","slug":"failed-to-download-image-from-url","errorCode":null,"errorMessage":"Failed to download image from {url}","messagePattern":"Failed to download image from (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/org/conductoross/conductor/ai/providers/gemini/GeminiVideoModel.java","lineNumber":180,"sourceCode":"            }\n\n        } catch (Exception e) {\n            log.error(\"Failed to check Gemini Veo video status for operation {}\", jobId, e);\n            throw new RuntimeException(\"Failed to check video status: \" + e.getMessage(), e);\n        }\n    }\n\n    private byte[] downloadFromUrl(String url) {\n        okhttp3.Request request = new okhttp3.Request.Builder().url(url).get().build();\n        try (okhttp3.Response response = httpClient.newCall(request).execute()) {\n            if (response.body() == null) {\n                throw new RuntimeException(\"Empty response downloading image from \" + url);\n            }\n            return response.body().bytes();\n        } catch (RuntimeException e) {\n            throw e;\n        } catch (Exception e) {\n            throw new RuntimeException(\"Failed to download image from \" + url, e);\n        }\n    }\n}\n","sourceCodeStart":162,"sourceCodeEnd":184,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/ai/src/main/java/org/conductoross/conductor/ai/providers/gemini/GeminiVideoModel.java#L162-L184","documentation":"GeminiVideoModel.downloadFromUrl() catches any checked Exception (IOException, etc.) during the input image download for image-to-video generation and wraps it. RuntimeException (including error 197) is rethrown unchanged first. The original exception is preserved as the cause. This covers transport-layer failures when fetching the input image from a URL.","triggerScenarios":"IOException during the OkHttp GET for the input image URL: connection timeout, SSL error, connection refused, DNS failure for the image host, or the image server returns a non-2xx status that OkHttp surfaces as an IOException.","commonSituations":"Network firewall blocking the external image host. Image host is down or rate-limiting. DNS resolution failure for the image URL domain. OkHttp connect timeout too short. Self-signed certificate on the image host causing TLS failure.","solutions":["Inspect getCause() for the specific IOException.","Verify the image URL host is reachable from the Conductor host (test with curl).","Use inline base64 (data: URI) to avoid the network download entirely — the code path supports it and bypasses downloadFromUrl.","If the image must be fetched from a URL, host it on a reliable CDN with proper TLS certificates.","Increase OkHttp connectTimeout if the image host is slow to respond."],"exampleFix":"// before — network download that may fail\nString imageUrl = \"https://internal-server/img.png\";\nVideoOptions opts = VideoOptionsBuilder.builder()\n    .inputImage(imageUrl).build();\n\n// after — inline base64, no download\nbyte[] imgBytes = Files.readAllBytes(Path.of(\"/data/img.png\"));\nString b64 = \"data:image/png;base64,\" + Base64.getEncoder().encodeToString(imgBytes);\nVideoOptions opts = VideoOptionsBuilder.builder()\n    .inputImage(b64).build();","handlingStrategy":"retry","validationCode":"// Pre-validate the input image URL reachability\nvoid validateInputImageReachable(String url) {\n    if (url == null || !url.startsWith(\"http\")) return;\n    try {\n        java.net.HttpURLConnection conn =\n            (java.net.HttpURLConnection) new java.net.URL(url).openConnection();\n        conn.setRequestMethod(\"HEAD\");\n        conn.setConnectTimeout(5000);\n        int code = conn.getResponseCode();\n        if (code != 200) {\n            throw new IllegalArgumentException(\n                \"Input image URL returned HTTP \" + code + \": \" + url);\n        }\n    } catch (java.io.IOException e) {\n        throw new IllegalArgumentException(\n            \"Cannot reach input image URL: \" + url, e);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return videoModel.call(videoPrompt);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Failed to download image\")\n            && e.getCause() instanceof java.io.IOException) {\n        // Transient network error — retry once\n        Thread.sleep(3000);\n        return videoModel.call(videoPrompt);\n    }\n    throw e;\n}","preventionTips":["Use inline base64 (data: URI) for input images to bypass downloadFromUrl entirely.","If using a URL, ensure the image host is reachable from the Conductor host and has valid TLS.","Verify DNS resolution for the image URL domain.","Implement retry with backoff for transient IOException causes.","Increase OkHttp connectTimeout if the image host is slow."],"tags":["gemini","video","download","network","io","image-to-video"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}