Seedance or Kling job failed: could not download an input media URL

A Seedance or Kling job can fail with 'Could not download an input media URL'. Why Sume rejects a frame or reference URL, and a preflight check for it.

5 min readSume
All posts

When a Seedance or Kling job on Sume fails with Could not download an input media URL (image_url). Verify the URL is publicly reachable, then retry., the clip never started: Sume could not fetch one of the images or videos you pointed at. The fix is to make that URL a plain, public HTTPS link that returns the file without a login, a signature that expires, or a hotlink check.

The message is deliberate. Sume remaps the internal worker error into a public one on GET /v1/videos/{id}, and keeps the offending URL out of the text. This post covers where the message appears, which request fields it can point at, and a small preflight script so you find the bad URL before you pay for a reservation.

Where does this error show up?

On the OpenRouter-shaped route the failed poll looks like this: status: failed with the sentence above in error. The content endpoint answers 409 job_failed with the same message, so a download script learns the cause too, as covered in the 409 post. The text is the same public remap behind GET /v1/jobs/{id}/status, not the internal Provider job failed. wrapper.

Some bad inputs are caught earlier. The errors page lists image_not_fetchable and input_media_unreachable under backpressure and fetch errors, meaning Sume could not fetch or mirror the media safely. Those come back at submit time with a request id rather than as a failed job.

Which request fields can carry the bad URL?

The field name in the message tells you which one to check. Seedance models take all three kinds of input; kling-3 takes first and last frames only.

Media URL fields on /v1/videos, read 2026-10-02
FieldSeedance 2.xkling-3
frame_images (first_frame, last_frame)AcceptedAccepted
input_references: image_urlAcceptedRejected (400)
input_references: video_urlAcceptedRejected (400)
input_references: audio_urlAccepted, needs an image or video referenceRejected (400)

What counts as a reachable URL?

Sume's media inputs page states the rule for its launch workflows: input URLs must be fetchable public HTTPS. Localhost, private-network addresses, non-HTTP URLs, signed or private URLs, and mismatched content types are rejected before generation. The video surfaces document the same requirement: use public HTTPS media URLs only.

In practice the usual culprits are an expiring object-storage link that lapsed between your upload and the job starting, a CDN that blocks requests without a browser user agent, and a URL that returns an HTML page with a 200 status. A frame URL that works in your browser while logged in is not evidence that Sume can fetch it.

How do I check URLs before submitting?

This script sends a HEAD request to each URL, follows redirects, and checks the status and content type. It cannot prove Sume's fetcher will succeed, but it catches the common failures for free.

import sys, requests

def check(url: str, want: str = "image/") -> str:
    if not url.startswith("https://"):
        return "not https"
    try:
        r = requests.head(url, allow_redirects=True, timeout=15)
    except requests.RequestException as e:
        return f"unreachable: {e.__class__.__name__}"
    ctype = r.headers.get("content-type", "")
    if r.status_code != 200:
        return f"status {r.status_code}"
    if not ctype.startswith(want):
        return f"content-type {ctype or 'missing'}"
    return "ok"

if __name__ == "__main__":
    for u in sys.argv[1:]:
        print(u, "->", check(u))

Do I pay for a job that failed on a bad URL?

Sume reserves the estimated cost when it accepts the job, captures it on success, and releases or refunds the reservation on failure where applicable. The refund behavior is the same one described in failed or canceled Seedance and Kling jobs. Check usage.cost on the poll response afterward rather than assuming.

After you fix the URL, resubmit as a new job. If you retry the same request body with the same Idempotency-Key, a replay returns the original job, which is the failed one. Use a fresh key for a changed input.

What is the most reliable way to host the input?

Import the file so Sume hosts it, then reference the Sume URL. POST /v1/media-imports pulls a public file into your workspace's media.sume.com storage, which removes the dependency on your own server's uptime and headers at the moment the job runs. Generated artifacts already live there, which makes chaining a first-frame still from one job into the next straightforward.

Whichever route you choose, keep the source link valid for the whole life of the job, including time in the queue. A job waiting for a slot fetches its inputs later than the moment you submitted it.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume