File validators
What is a file validator?
A file validator is a small rule that checks one file at a time. It looks at the file’s details (like image dimensions, metadata, duration, or other properties) and decides whether the file is allowed.
- If the file breaks your rule, the validator reports an error (with a short message users can see).
- If everything is okay, it reports nothing and the file is accepted.
Use file validators when you want to keep uploads clean and on-brief without reviewing files manually.
How it can be used
- Enforce image shape or quality (for example, minimum width/height or a specific aspect ratio like 1:1 or 16:9).
- Filename specific patterns.
- Require certain metadata (for example, EXIF camera tag present, or PDF page count in a range).
- Disallow specific content types (for example, animated GIFs for hero images).
- Enforce video duration limits (for example, max 30 seconds).
If you need rules that depend on multiple files together (for example, “exactly one cover image plus three gallery images,”), use a collection validator instead.
What users will see
When a file doesn’t meet your rule, the uploader shows a clear message telling the user what to fix. Your team can also read the same results through events and the API for logging or analytics. See: Events and Uploader API.
Validation model and signature
A validator descriptor can be one of the following:
- Sync validator function
See also: OutputFileEntry, UploaderPublicApi
- Async validator function
See also: OutputFileEntry, UploaderPublicApi, AbortSignal
- Object
runOn
decides when the validator runs:
- add — when the file is added to the uploader (before upload). Use this for checks that depend on the file itself.
- upload — after a successful upload (server-side fileInfo may be available). Use this for checks that depend on
fileInfo
that appears only after upload. - change — when the file is added, uploaded, or whenever the file is being edited using the Image Editor
By default, validator runs on change
if not specified.
Error type returned on failure:
Here, payload
is an optional object where you can include extra details about the error (for example, actual vs expected dimensions) and then catch them in your app via events or the API.
Sync validators
Best for simple, instant checks that use properties already on the file entry (for example, filename rules or basic pattern checks).
Example: Only allow spaces in filenames
Async validators
Best for heavier or deferred checks that run in the browser or on your server (for example, content heuristics).
Example: Only allow XLS tables with a specific sheet name
In this example we use add
to run the validator when the file is added only, because we rely on the file object, so running it again on change
or upload
would be redundant.
Async validators receive an AbortSignal as the third argument. The uploader aborts your validator when the file is removed or when it exceeds the configured timeout (set via validationTimeout).
If your validator was aborted due to these reasons, its result is ignored and treated as if it returned nothing (the file passes validation).
If your validator exceeds the timeout, the uploader won’t re-run it again for that file even if the runOn
condition is met again.
If your validator throws an error (for example, due to a network failure), the uploader treats it as a successful validation (the file passes validation).
Errors API
When a file fails validation, the uploader shows the error message to users in the UI. The same error details are also available via events and the Uploader API for logging or analytics.
Example: Read errors from the change
event
See also: Events
Example: Read errors from the Uploader API
See also: Uploader API
Each error from custom validators has the following shape:
Where message
and payload
come from your validator return value.
Error localization
Show error messages in the user’s language:
- Single-language projects: return plain strings from your validators.
- Multi-language projects: define localization keys, extend your locales, and reference those keys from validators (for example via the API helper).
Learn how to set up keys and extend locales: Localization
Validation queue
Validation for each file runs through a shared queue. This keeps the UI responsive when many files are added at once and prevents heavy checks from spiking CPU usage.
How it works:
- Every file validators run (sync or async) is scheduled as a task in the queue.
- The queue is shared across files; tasks are interleaved fairly.
- The number of tasks that can run in parallel is controlled by validationConcurrency.
- If a task runs too long, it can be aborted based on validationTimeout (async validators receive an AbortSignal).
This queue applies to both your custom validators and built-in checks (e.g., images-only, file size, and file type). That way, all validation work follows the same scheduling rules.
Caveats
- It’s expected that validator function won’t change by reference during the uploader lifecycle. If you’re using some reactive framework (React, Vue, etc.), make sure to memoize your validator functions.
OutputFileEntry
available properties could vary based on the file status and upload source:- For example,
fileInfo
is only available after a successful upload (from local file or remote sources like URL or social) file
(the original File object) is only available for local files and not for remote sources.cdnUrl
andcdnUrlModifiers
are only available after a successful upload and could be changed by image editing. If you need to validate these, userunOn: 'change'
to re-validate after edits.
- For example,
Best practices
- Choose the right
runOn
for your rule to avoid redundant checks:- Use
add
for checks that depend only on the file itself (for example, filename rules or basic pattern checks). - Use
upload
for checks that depend onfileInfo
that appears only after upload (for example, image dimensions or EXIF metadata). - Use
change
for checks that should run whenever the file is added, uploaded, or edited (for example, if you want to re-validate after image edits).
- Use
- Adjust concurrency based on your validator complexity (default is 100):
- Use lower concurrency for CPU or network heavy work (uploading files to the server, WASM, deep inspection).
- Use higher concurrency for lightweight rules to speed up validation for large selections.
- Adjust timeout based on your async validator average execution time (default is 15 seconds)