Avatar photo URL rejected: http, a port, a password or localhost

Sume refuses an avatar image_url that is not public HTTPS: no http, port, user:password or localhost. It fails on validation, with no fetch. Fix and retry.

4 min readSume
All posts

Sume rejects an avatar image_url with 400 invalid_request when it uses http://, names localhost or a private address, includes a user:password@ part, or sets an explicit port such as :8443. The rejection happens on validation, before Sume makes a single request to your host, so nothing is fetched and no job is created. The docs say the same in one line: the URL must be a fetchable public HTTPS image URL, and Sume rejects localhost, private-network, non-HTTPS and non-image responses (Create new avatar, read 2026-10-05).

A quick way to remember the rule is that Sume only accepts the kind of URL a stranger's browser could open: public, encrypted, on the default port, with no login embedded in the address. If your link needs a VPN, a cookie, a header or a password in the URL, Sume cannot use it. The fix is almost always to publish a copy of the photo at a link that follows those four properties, then pass that link as input.image_url. Doing this before the call avoids a round trip and keeps the failed request out of your logs.

Six URLs the tests refuse

The API suite pins six cases. Each one returns 400 invalid_request with the network untouched, on both the create route and the older model-run route.

  • Use https:// only.
  • Drop the port: serve the file on 443.
  • Remove user:password@ and use a query token if you need a secret.
  • Use a public DNS name, not localhost, .internal, .local, .test or a private range.
  • Test the URL from outside your own network.
Avatar photo URLs and what Sume does, read 2026-10-05
URL shapeProblemResult
http://assets.example.com/photo.pngNot HTTPS400 invalid_request
https://localhost/photo.pngLoopback host400 invalid_request
https://127.0.0.1/photo.pngLoopback address400 invalid_request
https://169.254.169.254/latest/meta-dataLink-local address400 invalid_request
https://user:password@assets.example.com/photo.pngCredentials in the URL400 invalid_request
https://assets.example.com:8443/photo.pngExplicit port400 invalid_request

What counts as private

The private-host list is a name and prefix check on the hostname: localhost, names ending in .localhost, .internal, .local or .test, 0.0.0.0, 127. addresses, 10., 169.254., 192.168., 172.16 to 172.31, and IPv6 loopback, fc, fd and fe80 ranges. A staging bucket on an internal DNS name is therefore refused even if it is reachable from your own network.

Fix the URL

Move the photo to a public host on port 443 and keep the secret in the query string, not in the userinfo part. A query token is allowed: the same test suite sends photo.txt?token=private through the fetch and asserts that the error never echoes it. The curl below is a valid create call with a hosted photo.

curl -X POST https://api.sume.com/v1/avatar-1.0/generate \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: avatar-photo-url-fix-001" \
  -d '{
    "avatar_handle": "reference_presenter",
    "input": {
      "type": "photo",
      "image_url": "https://assets.example.com/headshot.jpg?token=abc123"
    }
  }'

Why the rules exist

These are not Sume-specific whims. They are the standard server-side request forgery guard: a service that fetches URLs on your behalf must not be steered at internal addresses, cloud metadata endpoints, or authenticated URLs. That is why the metadata address 169.254.169.254 appears in the test list, next to loopback.

For you the practical consequence is hosting. A photo on a laptop tunnel, a staging bucket on an internal domain or a private network storage endpoint cannot be used directly. Copy it to a public bucket or CDN first.

Which code you will see

Errors on this path include details.field set to file.url, and details.suggested_input. For a URL that was never fetched, the two codes you may meet are invalid_request for the shape problems above and image_not_fetchable once a fetch was tried and failed. Branch your client on the code, not on the message text, because messages can be reworded and codes are the contract described in the error reference.

What comes after validation

Passing validation is only the first gate. The next gates are the content type (unsupported_image_type) and, when your host redirects, the redirect rules. The shared image_not_fetchable code in the error table lists the same advice: use a public HTTPS image URL and retry.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume