go-gitea/gitea · warning

Unable to render the PDF file

Error message

Unable to render the PDF file

What it means

Thrown by Gitea's in-place PDF render plugin when viewing a .pdf blob in the repository file viewer. It dynamically imports the pdfobject library and calls PDFObject.default.embed(fileUrl, container); pdfobject returns false (rather than throwing) when it detects the browser cannot display PDFs inline, and the plugin converts that false into this error.

Source

Thrown at web_src/js/render/plugins/inplace-pdf-viewer.ts:15

import type {InplaceRenderPlugin} from '../plugin.ts';

export function newInplacePluginPdfViewer(): InplaceRenderPlugin {
  return {
    name: 'pdf-viewer',

    canHandle: (filename: string, _mimeType: string): boolean => filename.toLowerCase().endsWith('.pdf'),

    async render(container: HTMLElement, fileUrl: string): Promise<void> {
      const PDFObject = await import('pdfobject');
      // TODO: the PDFObject library does not support dynamic height adjustment,
      // TODO: it seems that this render must be an inplace render, because the URL must be accessible from the current context
      container.style.height = `${window.innerHeight - 100}px`;
      if (!PDFObject.default.embed(fileUrl, container)) {
        throw new Error('Unable to render the PDF file');
      }
    },
  };
}

View on GitHub (pinned to 43ace7cc8a)

Solutions

  1. Open the 'Raw' / 'Download' link for the PDF instead of the in-place viewer — the file itself is fine, only inline rendering failed
  2. Enable the browser's native PDF viewer (Firefox: about:preferences > Applications > pdfjs enabled; check group policy on managed browsers)
  3. Adjust CSP on the Gitea deployment so object/embed for the PDF blob URL is allowed
  4. If this is a custom build, verify the pdfobject dependency is present and the container has non-zero height before render

Example fix

// before
if (!PDFObject.default.embed(fileUrl, container)) {
  throw new Error('Unable to render the PDF file');
}

// after (fall back to a plain download link instead of erroring)
if (!PDFObject.default.embed(fileUrl, container)) {
  container.textContent = '';
  const a = document.createElement('a');
  a.href = fileUrl;
  a.textContent = 'Open PDF in a new tab';
  a.target = '_blank';
  a.rel = 'noopener';
  container.append(a);
  return;
}
Defensive patterns

Strategy: fallback

Validate before calling

// Best-effort capability probe before rendering
const canRenderPdfInline = (): boolean =>
  typeof navigator !== 'undefined' && navigator.pdfViewerEnabled !== false;

Type guard

const supportsInlinePdf = (): boolean =>
  (navigator as Navigator & {pdfViewerEnabled?: boolean}).pdfViewerEnabled === true;

Try / catch

try {
  await plugin.render(container, fileUrl);
} catch (e) {
  // fall back to a raw link; the file itself is downloadable regardless of inline support
  container.replaceChildren(createAnchor(fileUrl));
}

Prevention

When it happens

Trigger: PDFObject.embed returns false: the browser lacks a built-in PDF viewer (or has it disabled, e.g., pdfjs.disabled in Firefox), the container element is hidden/zero-sized at embed time, or the browser refuses inline embedding for the blob/file URL (strict CSP framing rules, downloaded-marked content).

Common situations: Browsers or enterprise policies that disable the embedded PDF viewer; mobile browsers with no inline PDF support; strict Content-Security-Policy on a custom Gitea deployment blocking the object/embed pdfobject creates; very old browsers without PDF plugin support.

Related errors


AI-assisted analysis of go-gitea/gitea@43ace7cc8a (2026-08-15). Data as JSON: /api/errors/8e7b96234264f002. Report an issue: GitHub.