gitroomhq/postiz-app · error · HttpException
All media must be uploaded through our upload API route and
Error message
All media must be uploaded through our upload API route and contain the domain: ${process.env.RESTRICT_UPLOAD_DOMAINS} What it means
createPost rejects any image whose path does not contain the RESTRICT_UPLOAD_DOMAINS env value. When media domain restriction is enabled, all media referenced in posts must have been uploaded through the platform's own upload API route, so third-party/hotlinked media URLs are refused with a 400.
Source
Thrown at apps/backend/src/public-api/routes/v1/public.integrations.controller.ts:215
Sentry.metrics.count('public_api-request', 1);
const body = await this._postsService.mapTypeToPost(
rawBody,
org.id,
rawBody?.type === 'draft' || true
);
body.type = rawBody.type;
if (
process.env.RESTRICT_UPLOAD_DOMAINS &&
body.posts.some((p) =>
p.value.some((a) =>
a.image.some(
(i) => i.path.indexOf(process.env.RESTRICT_UPLOAD_DOMAINS) === -1
)
)
)
) {
throw new HttpException(
{
msg: `All media must be uploaded through our upload API route and contain the domain: ${process.env.RESTRICT_UPLOAD_DOMAINS}`,
},
400
);
}
// Server-side validation — same rules as the dashboard, surfaced as a
// readable 400 (see PostValidationExceptionFilter).
const validation = await this._postsService.validatePosts(
org.id,
body.posts
);
const fail = (item: (typeof validation)[number], error: string) => {
throw new PostValidationException({
provider: item.identifier,
name: item.name,View on GitHub (pinned to 0f1647f749)
Solutions
- First upload the image via the public upload endpoint and use the returned URL in the post
- If self-hosting, set RESTRICT_UPLOAD_DOMAINS to your own upload/CDN domain so platform-uploaded media passes the check
- If you intentionally want external media allowed, unset/empty RESTRICT_UPLOAD_DOMAINS (only if your deployment's security model permits)
- Ensure the configured domain matches exactly the domain in returned upload URLs (no scheme/port mismatch in the substring check)
Example fix
// before
{ "image": [{ "path": "https://images.example.com/cat.jpg" }] }
// after
const upload = await postiz.upload.fromUrl({ url: 'https://images.example.com/cat.jpg' });
{ "image": [{ "path": upload.url }] } // served under RESTRICT_UPLOAD_DOMAINS Defensive patterns
Strategy: validation
Validate before calling
const domain = process.env.RESTRICT_UPLOAD_DOMAINS;
const paths = post.posts.flatMap(p => p.value.flatMap(v => v.image ?? []).map(i => i.path));
if (domain && paths.some(p => !p.includes(domain))) {
// upload these through the API first, then swap in returned URLs
} Type guard
const isAllowedMediaPath = (path: string): boolean => !process.env.RESTRICT_UPLOAD_DOMAINS || path.includes(process.env.RESTRICT_UPLOAD_DOMAINS);
Try / catch
try {
await api.createPost(body);
} catch (e) {
if (String(e?.response?.data?.msg).includes('RESTRICT_UPLOAD_DOMAINS')) {
// re-upload media via the upload route and retry with returned URLs
}
} Prevention
- Always upload media through the platform upload API and reference returned URLs
- Self-hosted: set RESTRICT_UPLOAD_DOMAINS to your own upload domain
- Never hotlink third-party image URLs in post payloads
When it happens
Trigger: POST /public/v1/posts with an image entry whose path is an external URL (e.g. https://images.unsplash.com/...) while the RESTRICT_UPLOAD_DOMAINS env var is set. The check is a substring indexOf on each image path, so any media not originating from the configured upload domain fails.
Common situations: RESTRICT_UPLOAD_DOMAINS set in the environment (often by default or copied from production .env) while the client hotlinks external images; custom self-hosted deployments forgetting to point the env at their own upload/CDN domain; clients migrating from an API that allowed arbitrary URLs.
Related errors
- File is too large.
- Unsupported file type.
- Failed to fetch URL
- Post validation failed
- Integration not allowed
AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27).
Data as JSON: /api/errors/771fd64fcb3e67f0.
Report an issue: GitHub.