epubcheck is the canonical conformance checker for EPUB, maintained by the DAISY Consortium and the W3C community. It reads your file against the EPUB specification and reports every deviation as an ERROR or a WARNING, each tagged with a short code such as RSC-005. The codes look cryptic, but almost all of them are mechanical: a missing file, an attribute in the wrong place, or a resource that should not be there.
This guide walks the error families you will actually hit, what causes each one, and the typical fix. The golden rule: clear every ERROR line first — errors break conformance and can stop reading systems from opening the book — then work through the WARNING lines. Origami runs the same epubcheck engine, explains every finding in plain language, and sorts the blockers to the top so you know exactly what to touch first.
Schema errors: RSC-005
RSC-005 is the workhorse error, and the one that alarms people most. It means a file failed schema validation against the spec — the XML is well formed, but something in it is not allowed where you put it. Common triggers: an attribute that does not belong on an element, an element nested inside one that cannot contain it, a value outside the permitted list, or a stray property on a spine itemref.
The text after the code is the actual instruction — read it literally. A message like “attribute X not allowed here” tells you precisely which attribute to remove or move. Fixes are almost always local: delete the offending attribute, re-nest the element, or correct the value. Fix one, re-run, and a surprising number of RSC-005 lines often collapse to a single root cause repeated across chapters.
Missing and remote resources
RSC-007 and RSC-001 mean epubcheck followed a reference — a stylesheet, image, font, or a spine entry — and could not find the target inside the container. The cause is nearly always a path or case mismatch: a href points to images/Cover.jpg but the file is images/cover.jpg, or a file was renamed while its reference was not. EPUB paths are case sensitive; fix the path or restore the missing file.
RSC-006 flags a remote resource — a URL pointing outside the EPUB. The spec only permits remote references for a narrow set of media, such as audio and video; everything else, including images, fonts, and stylesheets, must be packaged inside the container. The fix is to download the asset, add it to the manifest, and repoint the reference to the local copy.
The package document: OPF errors
OPF-* errors come from the .opf package document — the manifest, metadata, and spine. The most frequent: a file that exists in the container but is not declared in the manifest (or is declared but missing), a spine that references an id with no matching manifest item, or required Dublin Core metadata that is absent or malformed, such as a missing dc:identifier, dc:title, or dc:language.
Treat the OPF as the source of truth: every content file must appear once in the manifest with the correct media type, and every spine itemref must point to an existing manifest id. Add the missing declaration, correct the media type, or supply the required metadata value, and the cascade of downstream errors usually clears with it.
Markup, navigation and packaging
HTM-* errors mean the XHTML itself is malformed or uses something the spec disallows — an unclosed tag, an undeclared namespace, or a deprecated construct. Because EPUB content is XHTML, it must be well formed XML: every tag closed, every attribute quoted. NCX and navigation errors point at the table of contents — a broken link in the nav document, or a mismatch between the nav and the spine order.
PKG-* errors are about how the ZIP is assembled. The classic one: the mimetype file must be the first entry in the archive and stored uncompressed, with no extra bytes. If your zipping tool compressed it or reordered entries, epubcheck complains before it even reads your content. Re-package with the mimetype first and uncompressed — most EPUB export tools handle this automatically, so this usually means avoiding a manual re-zip.
The fix, step by step
-
1
Validate and read the raw report
Run your EPUB through epubcheck 5.x and capture the full output. Every line carries a code, a severity, and a file-and-line location — that triple is your map to the exact spot that needs a change. Do not guess; the report already names the file.
-
2
Sort by severity, blockers first
Separate errors from warnings. Errors break conformance and can stop reading systems from opening the book, so clear every one before you touch a single warning. Warnings are advisory and can wait until the errors are gone.
-
3
Fix by family, container outward
Group the findings — schema, resources, package document, markup — and start at the container: mimetype and packaging first, then the OPF, then the individual content files. Fixing a root cause often clears several lines at once.
-
4
Re-validate until the report is clean
Run epubcheck again after each batch of fixes. Codes cascade, so one correction can resolve or reveal others. Repeat until zero errors remain, then decide which warnings are worth clearing for your readers.
The error codes, one by one
Every block below has the same five parts: the line epubcheck actually prints, what it means, why it happens, the fix, and the error it is most often confused with. Jump straight to a code, or search this page for the phrase you pasted out of your report.
RSC-005 — Error while parsing file
What epubcheck prints:
Error while parsing file: %1$s
- What it means
- The file is well-formed XML, but it broke a rule of the EPUB schema: something is not allowed where you put it. Everything after the colon is the schema validator’s own text, quoted verbatim by epubcheck.
- Why it happens
- An attribute that does not belong on that element, an element nested inside one that cannot contain it, a value outside the permitted list, or a stray property on a spine itemref.
- The fix
- Read the message literally — it names the attribute or element at fault. Delete it, re-nest it, or correct the value, then re-run. Dozens of RSC-005 lines usually collapse to one template mistake repeated across every chapter.
- When it is not this
- Because epubcheck quotes the schema validator’s raw text here, the message you are looking at may carry no code of its own. If you pasted a phrase out of your report and cannot find it anywhere on this page, it is almost certainly a schema message nested inside RSC-005 — start here rather than hunting for a code that does not exist.
RSC-007 — Referenced resource could not be found in the EPUB
What epubcheck prints:
Referenced resource "%1$s" could not be found in the EPUB.
- What it means
- epubcheck followed a reference — an image, a stylesheet, a font, a spine entry — and the target is not inside the container.
- Why it happens
- Nearly always a path or case mismatch: a href points at images/Cover.jpg while the file is images/cover.jpg, or a file was renamed and its references were not.
- The fix
- Match the reference to the real filename and folder exactly. EPUB paths are case sensitive and resolve relative to the file that contains them, not to the root of the book. Then re-validate.
- When it is not this
- If the file is in the container and epubcheck still complains, the problem is declaration, not location: that is RSC-008, or OPF-003 seen from the package’s side.
RSC-008 — Referenced resource is not declared in the OPF manifest
What epubcheck prints:
Referenced resource "%1$s" is not declared in the OPF manifest.
- What it means
- The file exists and the path resolves, but the package document never declares it. To a reading system, an undeclared resource does not exist.
- Why it happens
- An asset added by hand after export — a font, a late image, a stylesheet dropped into the folder without anyone touching the OPF.
- The fix
- Add an item to the manifest with a unique id, the href relative to the OPF’s own folder, and the correct media-type. If the resource is referenced from the spine, add the matching itemref too.
- When it is not this
- RSC-007 means the reference has no file. This means the file has no declaration. They look alike in a report and have opposite fixes.
RSC-001 — File could not be found
What epubcheck prints:
File "%1$s" could not be found.
- What it means
- A path named in the package structure resolves to nothing inside the container.
- Why it happens
- An entry that never made it into the ZIP, or a path in META-INF/container.xml or the OPF that points somewhere the file is not.
- The fix
- Check that container.xml names the real .opf, then confirm every manifest href resolves relative to the folder the OPF lives in. Repackage once the paths agree.
- When it is not this
- RSC-007 is a broken reference from inside your content. RSC-001 is usually a broken path in the packaging around it, so look at the container before you open a chapter.
RSC-006 — Remote resource reference is not allowed in this context
What epubcheck prints:
Remote resource reference is not allowed in this context; resource "%1$s" must be located in the EPUB container.
- What it means
- Something the reading system must fetch to render the page lives at a URL outside the book. The specification only permits remote references for a narrow set of media, such as audio and video.
- Why it happens
- A hosted webfont, an image still pointing at a CDN, or a stylesheet include that survived from an HTML template.
- The fix
- Download the asset, add it to the manifest, and repoint the reference at the local copy. A book that depends on a server is a book that stops working offline.
- When it is not this
- A hyperlink in your prose to an external site is fine and is not what this reports. The rule is about resources needed to render, not destinations a reader may choose to visit.
OPF-003 — Item exists in the EPUB, but is not declared in the OPF manifest
What epubcheck prints:
Item "%1$s" exists in the EPUB, but is not declared in the OPF manifest.
- What it means
- The same fact as RSC-008, reported from the package’s side: there is a file in the container the manifest never mentions.
- Why it happens
- Leftovers, most of the time — an unused cover, an editor’s backup file, fonts from a design that was replaced, operating-system metadata that got zipped in.
- The fix
- Declare it if the book needs it; delete it from the container if it does not. An undeclared file still ships and still costs your reader the download.
- When it is not this
- RSC-007 is a reference with no file. This is a file with no reference. The report reads almost the same; the fixes point in opposite directions.
OPF-014 — The property should be declared in the OPF file
What epubcheck prints:
The property "%1$s" should be declared in the OPF file.
- What it means
- A content document uses a feature — scripting, MathML, SVG, a remote resource — that its manifest item is supposed to advertise through the properties attribute, and does not.
- Why it happens
- An SVG cover or an inline svg element added after export, MathML pasted in from another source, or a script added for one interactive figure.
- The fix
- Add the property epubcheck names to that item’s properties attribute in the manifest. Several properties on one item are separated by spaces.
- When it is not this
- OPF-015 is the mirror image: a property declared for a feature the file does not actually use. Adding properties “just in case” trades this error for that one.
OPF-030 — The unique-identifier was not found
What epubcheck prints:
The unique-identifier "%1$s" was not found.
- What it means
- The package element’s unique-identifier attribute points at the id of a dc:identifier, and no element with that id exists.
- Why it happens
- The identifier was rewritten — a new ISBN, a regenerated UUID — and its id attribute was dropped or renamed while the package attribute kept pointing at the old name.
- The fix
- Give the dc:identifier an id, and make unique-identifier on the package element name exactly that id. The two strings have to match character for character.
- When it is not this
- This is about the pointer, not the value. A book with a perfectly valid ISBN still fails here if nothing points at it, so do not go looking for a problem with the identifier itself.
PKG-006 — Mimetype file entry is missing or is not the first file in the archive
What epubcheck prints:
Mimetype file entry is missing or is not the first file in the archive.
- What it means
- The ZIP is assembled wrongly. epubcheck reaches this before it reads a single line of your content, which is why the rest of the report can look strangely short.
- Why it happens
- A re-zip by hand, or by an operating-system archiver that sorts entries alphabetically and puts META-INF first.
- The fix
- Rebuild the archive with the mimetype entry added first and stored uncompressed, then everything else. Most EPUB export tools do this for you — the fix is usually to stop re-zipping the folder manually.
- When it is not this
- Nothing here is a content problem. Do not go looking through your XHTML: no edit inside the book can clear this line.
PKG-007 — Mimetype file should only contain the string and should not be compressed
What epubcheck prints:
Mimetype file should only contain the string "application/epub+zip" and should not be compressed.
- What it means
- The mimetype entry is in the right place, but its contents or its storage are wrong.
- Why it happens
- A text editor that appended a newline or a byte-order mark, or a zipping step that compressed the entry along with everything else.
- The fix
- Write exactly the twenty characters application/epub+zip — no trailing newline, no BOM — and add the entry to the archive stored rather than deflated.
- When it is not this
- PKG-006 is about where the entry sits; this is about what is in it and how it was stored. Fixing one and re-running often just surfaces the other.
HTM-004 — Irregular DOCTYPE
What epubcheck prints:
Irregular DOCTYPE: found "%1$s", expected "%2$s".
- What it means
- A content document carries a doctype declaration that EPUB 3 does not expect.
- Why it happens
- An XHTML 1.1 or EPUB 2 doctype that survived a conversion, or a doctype carrying an internal subset so the file can use named HTML entities.
- The fix
- Replace the whole declaration with <!DOCTYPE html>. If the file relied on named entities, replace them with numeric references or the literal characters — an internal subset is not the way to keep them.
- When it is not this
- This is not about the XML declaration on the first line. That is a separate thing, it is allowed, and removing it will not clear this error.
NCX-001 — NCX identifier does not match OPF identifier
What epubcheck prints:
NCX identifier ("%1$s") does not match OPF identifier ("%2$s").
- What it means
- The legacy NCX table of contents carries a dtb:uid value that disagrees with the dc:identifier in the package document.
- Why it happens
- The OPF identifier was regenerated — a new ISBN for a new edition, a fresh UUID from an export — and the NCX kept the old one.
- The fix
- Copy the OPF’s dc:identifier value into the NCX’s <meta name="dtb:uid">. If you no longer support EPUB 2 reading systems, removing the NCX entirely is also a valid answer.
- When it is not this
- This does not mean your table of contents is broken. EPUB 3 navigation lives in the nav document; the NCX is the compatibility copy beside it, and only its identifier is at issue here.