conductor-oss/conductor · error · IOException
OpenAI Video download failed with status %d
Error message
OpenAI Video download failed with status %d
What it means
Thrown by OpenAIVideoApi.downloadVideo (the byte[] variant) when GET /v1/videos/{id}/content returns non-2xx. Unlike the streaming variant (224), this message omits the error body and reports only the status code. IOException is thrown inside a try-with-resources so the response is auto-closed.
Source
Thrown at ai/src/main/java/org/conductoross/conductor/ai/providers/openai/api/OpenAIVideoApi.java:199
}
/**
* Download the completed video as a byte array.
*
* @param videoId The video job ID
* @return byte array of the MP4 binary data
*/
public byte[] downloadVideo(String videoId) throws IOException {
Request request =
new Request.Builder()
.url(baseUrl + "/v1/videos/" + videoId + "/content")
.header("Authorization", "Bearer " + apiKey)
.get()
.build();
try (Response response = httpClient.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException(
"OpenAI Video download failed with status %d".formatted(response.code()));
}
ResponseBody body = response.body();
if (body == null) {
throw new IOException("OpenAI Video download returned empty body");
}
return body.bytes();
}
}
/**
* Download the thumbnail for a completed video.
*
* @param videoId The video job ID
* @return byte array of the thumbnail image (webp format)
*/
public byte[] downloadThumbnail(String videoId) throws IOException {
Request request =View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Gate the call on getVideoStatus()=='completed' first.
- Prefer downloadVideoStream for large videos to avoid loading the whole MP4 into a byte[].
- On 404/410 regenerate the video.
- If you need the error body for diagnosis, use downloadVideoStream which captures it.
Defensive patterns
Strategy: try-catch
Validate before calling
// Gate on completion before downloading
VideoStatusResponse status = videoApi.getVideoStatus(videoId);
if (!"completed".equalsIgnoreCase(status.status())) {
throw new IllegalStateException("Video not completed: " + status.status());
} Try / catch
try {
byte[] mp4 = videoApi.downloadVideo(videoId);
} catch (IOException e) {
if (e.getMessage().contains("status 404") || e.getMessage().contains("status 410")) {
// asset expired - regenerate
} else {
throw e;
}
} Prevention
- Only call downloadVideo after status is 'completed'.
- Prefer downloadVideoStream for large videos to avoid memory pressure.
- Treat 404/410 as terminal and regenerate.
- Use downloadVideoStream if you need the error body for diagnosis.
When it happens
Trigger: Downloading before completion (400/409), expired asset (404/410), invalid key (401), or rate limiting (429). Same failure modes as 224 but the byte[] path loses the response body detail for diagnosis.
Common situations: Calling downloadVideo prematurely, asset TTL elapsed, or transient download errors on large MP4s loaded fully into memory.
Related errors
- OpenAI Video download failed with status %d: %s
- OpenAI Video thumbnail download failed with status %d
- OpenAI Video API submit failed with status %d: %s
- OpenAI Video API status check failed with status %d: %s
- OpenAI Video download returned empty body
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/ae857ee5532803f4.
Report an issue: GitHub.