unslothai/unsloth · error · ValueError
Upscale would not enlarge this image: its longest side ({max
Error message
Upscale would not enlarge this image: its longest side ({max(iw, ih)}px) already meets the {max_side}px output limit. Use a smaller source image. What it means
In the upscale (hires-fix) workflow, the target size is computed as the input size times a factor clamped to [1.0, 4.0], then capped so the longest side does not exceed 2048px and snapped to a multiple of 16. If the source image's longest side already meets or exceeds the capped target, the 'upscale' would actually shrink or no-op, so the code refuses with this ValueError instead of returning a smaller image.
Source
Thrown at studio/backend/core/inference/diffusion.py:5388
pipe = self._workflow_pipe(state, state.family.inpaint_pipeline_class, workflow)
init_pil = decode_b64_image(init_image, mode = "RGB")
mask_pil = decode_b64_image(mask_image, mode = "L")
elif init_image is not None and upscale is not None and upscale > 1.0:
# Upscale (hires fix): enlarge with Lanczos, then re-run img2img at low strength to add detail.
workflow = "upscale"
pipe = self._workflow_pipe(state, state.family.img2img_pipeline_class, workflow)
init_pil = decode_b64_image(init_image, mode = "RGB")
iw, ih = init_pil.size
# Cap the factor, then the absolute output (longest side 2048); round to a multiple of 16 (VAE downsample + patch).
factor = max(1.0, min(float(upscale), 4.0))
tw_f, th_f = iw * factor, ih * factor
max_side = 2048
fit = min(1.0, max_side / max(tw_f, th_f))
tw = max(16, int(round(tw_f * fit / 16.0)) * 16)
th = max(16, int(round(th_f * fit / 16.0)) * 16)
# After the cap, the target must still exceed the input (else upscale shrinks it).
if max(tw, th) <= max(iw, ih):
raise ValueError(
f"Upscale would not enlarge this image: its longest side "
f"({max(iw, ih)}px) already meets the {max_side}px output limit. "
f"Use a smaller source image."
)
init_pil = init_pil.resize((tw, th), Image.LANCZOS)
if strength is None:
strength = 0.35 # hires-fix default: preserve content, add detail
elif getattr(state.family, "reference", False) and init_image is not None:
# FLUX.2 reference conditioning: the loaded pipe takes the reference via `image` and generates at the REQUESTED size.
workflow = "reference"
init_pil = decode_b64_image(init_image, mode = "RGB")
# Additional references (FLUX.2 combines a list); capped to bound VRAM.
ref_extra = [
decode_b64_image(x, mode = "RGB") for x in (reference_images or [])[:3]
]
elif init_image is not None:
workflow = "img2img"
pipe = self._workflow_pipe(state, state.family.img2img_pipeline_class, workflow)View on GitHub (pinned to 203007d190)
Solutions
- Downscale the source image so its longest side is comfortably below 2048px before requesting upscale (e.g. resize to 1024-1536px longest side).
- Skip the upscale flag and use plain img2img at the source resolution if enlargement is not needed.
- Raise the max_side cap in your own fork only if you have VRAM/headroom for larger outputs — stock builds cap at 2048.
Example fix
# before engine.generate(prompt=..., init_image=big_2048px_b64, upscale=2.0) # after from PIL import Image img = decode(b64); img.thumbnail((1536, 1536)) engine.generate(prompt=..., init_image=encode_b64(img), upscale=2.0) # 1536 -> ~3072 capped to 2048, still larger
Defensive patterns
Strategy: validation
Validate before calling
from PIL import Image
import io
MAX_SIDE = 2048
def upscale_viable(img_b64: str, upscale: float) -> bool:
img = Image.open(io.BytesIO(decode(img_b64)))
factor = max(1.0, min(float(upscale), 4.0))
tw, th = img.width * factor, img.height * factor
fit = min(1.0, MAX_SIDE / max(tw, th))
tw = max(16, int(round(tw * fit / 16.0)) * 16)
th = max(16, int(round(th * fit / 16.0)) * 16)
return max(tw, th) > max(img.size) Try / catch
try:
out = engine.generate(prompt=p, init_image=img_b64, upscale=2.0)
except ValueError as e:
if "would not enlarge" in str(e):
out = engine.generate(prompt=p, init_image=downscale_b64(img_b64, longest=1536), upscale=2.0)
else:
raise Prevention
- Pre-resize uploads so the longest side is 1024-1536px before requesting upscale.
- Do not chain upscale calls on outputs already at the 2048 cap.
When it happens
Trigger: Calling generate with init_image set, upscale > 1.0, and an input image whose max(iw, ih) is at or above 2048px (or close enough that the 16px rounding lands the target at or below the input). E.g. a 2048x1536 photo with upscale=2 would target 4096 -> capped to 2048 -> not larger than input.
Common situations: Feeding full-resolution phone photos (commonly 4000px+) into an img2img upscale endpoint; re-running upscale on an already-upscaled output that hit the 2048 cap.
Related errors
- upscale requires an input image (init_image).
- Unknown model_kind '{model_kind}'. Expected one of {sorted(_
- Invalid base64 image data: {exc}
- Image is too large ({w}x{h}); maximum is {max_side}px per si
- Local base_repo is not a diffusers pipeline directory (no {i
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/e49b3d5452491e29.
Report an issue: GitHub.