mozilla/pdf.js · error · FormatError
No domain or range
Error message
No domain or range
What it means
Thrown inside PDFFunction.constructSampled (FunctionType 0) when either the /Domain or /Range array on the function dictionary is missing or not a pure numeric array. Both are required by the PDF spec to define the input and output dimensionality of a sampled (table-lookup) function; without them interpolation cannot be set up.
Source
Thrown at src/core/function.js:172
}
return function (src, srcOffset, dest, destOffset) {
for (let i = 0, ii = fnArray.length; i < ii; i++) {
fnArray[i](src, srcOffset, dest, destOffset + i);
}
};
}
static constructSampled(factory, fn, dict) {
// See chapter 3, page 109 of the PDF reference
function interpolate(x, xmin, xmax, ymin, ymax) {
return ymin + (x - xmin) * ((ymax - ymin) / (xmax - xmin));
}
const domain = toNumberArray(dict.getArray("Domain"));
const range = toNumberArray(dict.getArray("Range"));
if (!domain || !range) {
throw new FormatError("No domain or range");
}
const inputSize = domain.length / 2;
const outputSize = range.length / 2;
const size = toNumberArray(dict.getArray("Size"));
const bps = dict.get("BitsPerSample");
const order = dict.get("Order") || 1;
if (order !== 1) {
// No description how cubic spline interpolation works in PDF32000:2008
// As in poppler, ignoring order, linear interpolation may work as good
info("No support for cubic spline interpolation: " + order);
}
let encode = toNumberArray(dict.getArray("Encode"));
if (!encode) {
encode = [];
for (let i = 0; i < inputSize; ++i) {View on GitHub (pinned to 5903d58d58)
Solutions
- Validate the PDF in Acrobat; if it works there, report the file to pdf.js maintainers as the constructor may need a fallback.
- If generating PDFs, always emit both /Domain and /Range as flat numeric arrays of even length for every type-0 function.
- Catch FormatError around render and skip the affected page/annotation.
- Run the PDF through qpdf --check to detect missing required function entries.
Example fix
// generating a sampled function: always include Domain and Range /* before << /FunctionType 0 /Domain [0 1] /Size [256] /BitsPerSample 8 /DataSource (...) >> */ // after << /FunctionType 0 /Domain [0 1] /Range [0 1 0 1 0 1] /Size [256] /BitsPerSample 8 /DataSource (...) >>
Defensive patterns
Strategy: try-catch
Validate before calling
function hasSampledFunctionDomainRange(dict) {
const d = dict.getArray?.('Domain');
const r = dict.getArray?.('Range');
return Array.isArray(d) && Array.isArray(r) &&
d.every(Number.isFinite) && r.every(Number.isFinite) &&
d.length % 2 === 0 && r.length % 2 === 0;
} Type guard
function isNumberArrayOfEvenLength(arr) {
return Array.isArray(arr) && arr.length % 2 === 0 &&
arr.every(x => typeof x === 'number' && Number.isFinite(x));
} Try / catch
try { await page.render({ canvasContext }).promise; }
catch (err) {
if (err?.name === 'FormatError' && /No domain or range/.test(err.message)) {
console.warn('Malformed sampled function; degrading page.');
} else throw err;
} Prevention
- When authoring Type 0 functions, always emit /Domain and /Range as numeric arrays.
- Use qpdf --check to catch missing required function entries.
- Isolate per-page rendering with try/catch.
When it happens
Trigger: A FunctionType 0 dictionary that lacks /Domain or /Range, or where one resolves to a non-number array (e.g. contains refs to non-numeric objects). Reached when rendering gradients, Indexed color spaces, or shading patterns that reference a sampled function.
Common situations: Corrupt/truncated PDFs, or PDFs produced by tools that omit Range on sampled functions. Encountered while opening specific test files known to have malformed CalRGB/Indexed lookups.
Related errors
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/21a5c6e9447cc67d.
Report an issue: GitHub.