Common symptoms and where to look. iiiris logs to stdout (or log.file);
the /admin/ dashboard shows per-route latency, per-cache stats,
and per-source health. Config fields referenced here are in
configuration.md.
The error body names the specific cause; the status code narrows it:
Status
Meaning
Check
400
Client-fault request: bad region/size/rotation/quality syntax, region origin outside the source, an upscale without ^, or a max_pixel_area / max_output_area guard exceeded.
The request URL grammar and the guard values in image.*.
401
Auth denied by the configured Authorizer.
iiif-auth.md — rules, patterns, and the access-service backend.
404
Identifier not found in the source (or a hook resolved it to a missing key).
The source path/key; if using a hook, what Resolve returns (hooks.md).
429
Per-IP concurrency cap hit.
Raise image.max_concurrent_per_ip (0 disables it), or rate-limit at a proxy.
500
Decode/encode or source-I/O failure.
The logs — e.g. libvips can't read the format, or the source errored. JP2/HTJ2K needs libvips built with OpenJPEG ≥ 2.5 (the release images bundle it).
image.max_concurrent too high for the source size (each in-flight decode holds its working set), or an unbounded cache.
Lower max_concurrent, or cap the cache (caches.*.max_bytes). mmap keeps filesystem-source memory independent of file size, so the render working set — not the source — dominates.
A cache grows without bound
caches.*.max_bytes: 0 is unbounded for heap/filesystem.
Set a byte cap, or use s3/redis (eviction via lifecycle policy / MAXMEMORY+TTL).
Renders slow or queuing
Cold/uncached decode of large masters is genuinely the work — check warm vs cold p95 in /admin/. If cores sit idle under load, concurrency is the limit.
Enable caches (caches.md). Raise image.max_concurrent above NumCPU for I/O-bound sources (network/EBS), where cores idle during reads; the default (NumCPU) suits CPU-bound local disk.
JPEG output larger than expected
Baseline JPEG is the default (it encodes ~3× faster than progressive).
Set image.jpeg_progressive: true if you want progressive (smaller, incremental-render) output at the encode-CPU cost.