n8n-io/n8n · warning · BadRequestError
Content not viewable
Error message
Content not viewable
What it means
BadRequestError (HTTP 400) 'Content not viewable' thrown at binary-data.controller.ts:89 when `action === 'view'` and the resolved MIME type is missing or not in `ViewableMimeTypes`. Viewable set: application/json; audio/{mpeg,ogg,wav}; image/{bmp,gif,jpeg,jpg,png,tiff,webp}; text/{css,csv,markdown,plain}; video/{mp4,ogg,webm}. HTML, SVG, and PDF are intentionally excluded (XSS / code-exec risk).
Source
Thrown at packages/cli/src/controllers/binary-data.controller.ts:89
}
}
private async setContentHeaders(
binaryDataId: string,
action: 'view' | 'download',
res: Response,
fileName?: string,
mimeType?: string,
) {
try {
const metadata = await this.binaryDataService.getMetadata(binaryDataId);
fileName = metadata.fileName ?? fileName;
mimeType = metadata.mimeType ?? mimeType;
res.setHeader('Content-Length', metadata.fileSize);
} catch {}
if (action === 'view' && (!mimeType || !ViewableMimeTypes.includes(mimeType.toLowerCase()))) {
throw new BadRequestError('Content not viewable');
}
if (mimeType) {
res.setHeader('Content-Type', mimeType);
}
res.setHeader('Content-Security-Policy', getHtmlSandboxCSP());
if (action === 'download') {
if (fileName) {
const encodedFilename = encodeURIComponent(fileName);
res.setHeader('Content-Disposition', `attachment; filename="${encodedFilename}"`);
} else {
res.setHeader('Content-Disposition', 'attachment');
}
}
}
}View on GitHub (pinned to 5ac6606e81)
Solutions
- Use `action=download` instead of `view` for non-viewable MIME types.
- If the type should be viewable, set the correct `mimeType` query param or fix the binary metadata at write time.
- Never request `view` for HTML/SVG/PDF — the allowlist will refuse by design.
Example fix
// before GET /binary-data?id=filesystem:report.html&action=view // 400 Content not viewable // after GET /binary-data?id=filesystem:report.html&action=download
Defensive patterns
Strategy: validation
Validate before calling
const VIEWABLE = ['application/json','audio/mpeg','audio/ogg','audio/wav','image/bmp','image/gif','image/jpeg','image/jpg','image/png','image/tiff','image/webp','text/css','text/csv','text/markdown','text/plain','video/mp4','video/ogg','video/webm'];
function canView(mimeType?: string) {
return !!mimeType && VIEWABLE.includes(mimeType.toLowerCase());
}
// action = canView(mt) ? 'view' : 'download' Type guard
const VIEWABLE = ['application/json','audio/mpeg','audio/ogg','audio/wav','image/bmp','image/gif','image/jpeg','image/jpg','image/png','image/tiff','image/webp','text/css','text/csv','text/markdown','text/plain','video/mp4','video/ogg','video/webm'] as const; const isViewable = (m?: string): m is string => !!m && (VIEWABLE as readonly string[]).includes(m.toLowerCase());
Try / catch
try { await get(req); } catch (e) { if (e instanceof BadRequestError && /not viewable/.test(e.message)) {/* fall back to download */} } Prevention
- Default to `action=download` for unknown or unsafe MIME types.
- Never request `view` for HTML/SVG/PDF — the allowlist refuses them by design.
- Record mimeType on the binary at write time so the viewer can decide.
When it happens
Trigger: Calling `GET /binary-data?id=...&action=view` on a binary whose MIME is `text/html`, `image/svg+xml`, `application/pdf`, an unknown type, or where no MIME is resolvable from metadata or query.
Common situations: Trying to inline-preview HTML/SVG/PDF outputs; attachments with missing/incorrect `mimeType`; frontend defaulting to `view` for unsafe types.
Related errors
- error.message
- Missing binary data ID
- Malformed binary data ID
- Invalid binary data mode
- ${binaryData.mimeType} is not a supported type of binary dat
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/415fc2b80c77406d.
Report an issue: GitHub.