Avatar photo 400 invalid_image: under 64 px or a 6:1 aspect ratio

Sume rejects an avatar photo that is not decodable, is under 64 px on a side, or is more than 6:1. The 400 invalid_image error reports width, height and reason.

4 min readSume
All posts

400 invalid_image on a Sume avatar photo means the file arrived with an accepted content type, but the pixels fail one of three checks: the header cannot be decoded as the type it claims, either side is under 64 px, or the long side is more than six times the short side. details.reason tells you which one: image_not_decodable, image_too_small or unsupported_aspect_ratio, with width and height on the last two.

Like every avatar photo check, it runs before any job is created, so nothing is queued and you can fix the picture and resubmit. The request shape is on Create new avatar, read 2026-10-05.

The three reasons

Sume reads the image header itself, for PNG, JPEG, WebP and GIF, instead of trusting the Content-Type. That is how a JPEG served with an image/png label ends up as image_not_decodable: the PNG signature is missing.

  • Check the file, not the label: open it and read the real dimensions.
  • Crop banners and strips to a portrait or square frame before upload.
  • Keep both sides at 64 px or more, and well above that for a usable face.
  • Log details.width and details.height from the error and compare with your stored values.
invalid_image reasons and thresholds, read 2026-10-05
details.reasonRuleExample that failsExample that passes
image_not_decodableHeader must parse as the declared type4 random bytes labeled image/pngA real PNG, JPEG, WebP or GIF
image_too_smallBoth sides at least 64 px63 x 40064 x 64
unsupported_aspect_ratioLong side / short side at most 61300 x 200 (6.5)1200 x 200 (exactly 6)

Check the numbers locally

The three rules fit in a few lines, so run them on your own files before you call the API. This sketch checks the numbers only; read the width and height with your image library of choice.

def check(width, height):
    if width < 64 or height < 64:
        return "image_too_small"
    if max(width, height) / min(width, height) > 6:
        return "unsupported_aspect_ratio"
    return "ok"

for size in [(63, 400), (64, 64), (1200, 200), (1300, 200), (1024, 1536)]:
    print(size, check(*size))

What to send instead

The error also sets details.suggested_input to clear_front_facing_image. That is the whole hint Sume gives, and it is a fair summary of what to send: a normal portrait crop, not a banner, not a thumbnail. A 9:16 or 3:4 phone photo is nowhere near the 6:1 limit, and neither is a square profile picture.

Sume does not promise that a photo which passes will look good as an avatar. The preflight is a gate for broken inputs. To judge the look of the person, create the avatar and review the first-frame stills in an avatar video preview before a full render.

Which common images trip the ratio rule

A 6:1 limit is generous. A 16:9 frame is 1.78:1, a 9:16 phone shot is 1.78:1, and even a 21:9 cinema crop is 2.33:1. The rule exists to stop banners, strips and sprite sheets, not to police normal photography. If you hit it, the usual cause is a cropped logo bar or a contact-sheet image that was uploaded as the headshot.

The 64 px floor is the same in both directions, so a tall thin 63 x 400 image fails on the small side even though its ratio of 6.35 would also fail. The API reports the first rule it trips, so fix both before you retry.

Log what Sume saw

Because the numbers come back in details.width and details.height, a client can log exactly what Sume saw. That is useful when your CDN resizes on the fly: the dimensions you stored may not be the dimensions served to Sume's fetch. Compare them before you blame the file.

Where undecodable files come from

Two quick causes explain most image_not_decodable errors. A CDN that converts formats on the fly can send AVIF bytes under a PNG label, and a download that was cut short has a header but no body. Re-download the file, open it, and host it again. For the type errors that come one step earlier, see unsupported_image_type.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume