Restrict and register image sizes
-
What you'll see
You just changed
sizePolicy, or you are adopting WebP/AVIF, and something breaks. The symptoms:- Images suddenly return 400 after switching to
strict— a size the page requests is not inallowedSizes. - An image comes back at a “nearly right” size under
auto— it was snapped to the closest allowed size. - A size generated in client-side JS never shows up in “Scan now” — the scan only reads server-side source.
.webp/.avifis served as JPEG for as long as the policy isopen.- Scaled images return 429 under load — the anti-DoS rate guard on scaling.
- Images suddenly return 400 after switching to
-
What's actually happening
The size key is
WxHxM— the same string as the URL segment.WxH(no third part) is mode0. There are three policy modes:Mode Behaviour open(default)Any size, only the maxDimensioncap applies..webp/.avifon the URL path is downgraded to JPEG/PNG.autoAccepts allowedSizes∪discoveredSizes. An unknown size snaps to the nearest allowed one; the list self-expands from traffic and scan.strictSame as auto, but an unknown size returns HTTP 400. No self-expansion.Two lists with different ownership:
allowedSizesis yours (owner-maintained, never touched by scan or passive discovery), whilediscoveredSizesis the machine's (append-only, deduped, passive growth capped at 100).Snapping under
autoonly matches within the same scaling mode. If no allowed size exists with the requested mode, the request is rejected instead of snapped — that is the “nearly right size” symptom when the mode does not line up.Under
open, a requested.webp/.avifon the URL path is downgraded to JPEG/PNG. This is a DoS defence (see Use AVIF and WebP image formats, #26952):openhas no size whitelist, so the URL could otherwise request arbitrary sizes in the heavier formats. Server-authoreddocly.scaleImageandattachFile64are not subject to the policy. -
What to do
Roll the policy on in order — start permissive, capture the real sizes, then lock down.
- Open Folder Properties → the “Image sizes” tab (requires publish rights on the folder).
- Set
sizePolicytoauto. This starts passive discovery and lets you scan. - Run “Scan now” (a static dry-run — it writes nothing), review the diff, then Apply changes.
- Promote the sizes you want to keep from Discovered to Allowed.
- Add client-JS-generated and dynamically computed sizes to
allowedSizesby hand — the scan never sees them. The same applies to anyWxHxMURL you assembled by hand in a template: the scan finds literallinkImagecalls, so a concatenated URL stays invisible and its size is refused once you switch tostrict. Convert those tolinkImage/linkFilebefore locking down — see Do not build file and image URLs by hand. - Switch to
strictand verify that no images return 400.
The image settings live in
#/images.json(in the folder's#system folder), shared per folder, keys read case-insensitively. The Image sizes tab and discovery write there — never to#/site.jsonand never to the app. Animagessection in#/site.jsonstill works, but Docly moves it to#/images.jsonthe first time it saves image settings. A site built on an app inherits the app's image settings key by key; a list such asallowedSizesin the site replaces the app's list as a whole (see Configure site settings and inherit them from the app).{ "defaultFormat": "webp", "sizePolicy": "auto", "onDisallowed": "nearest", "maxDimension": 2000, "allowedSizes": ["1200x800x0", "600x400x0", "128x128x1"], "discoveredSizes": ["1024x1024x0", "300x300x0"] }images.* Values Meaning defaultFormatauto|jpeg|png|webp|avifDefault output format. The file extension in linkImagealways overrides.sizePolicyopen(default) |auto|strictSee the mode table above. onDisallowednearest|rejectOverrides the default for an unknown size ( auto→nearest,strict→reject).maxDimensionpx, default 2000 Hard cap on W and H in all modes, including open. 0/unset ⇒ 2000.allowedSizes["WxHxM", …]Owner-maintained. Never touched by scan or passive discovery. No cap. discoveredSizes["WxHxM", …]Machine-maintained. Append-only + dedupe. Passive growth capped at 100. quality1–100, or per format: { "jpeg": 90, "webp": 78, "avif": 50, "default": 70 }Encoder quality for scaled images. Per-format key first, then the number or default, then the built-in default. PNG is lossless and ignores it. Never settable from the URL.Watch out:
strictwith an emptyallowedSizesrejects every scaled image with 400 (warningstrict_no_sizes). Promote at least one real size before you switch.The full M-mode table (
-1…5), the snapping algorithm and everylinkImageoverload live in the reference pages — see linkImage, scaleImage and the site.json reference.
Last reviewed 17 Oct 2026