Skip to content
Novus Examples
4 min readNovus ExamplesGuideAdvancedv2026.09

Test EPUB Readers With the Books That Break Them

Obfuscated fonts, an NCX that disagrees with the nav document, vertical Japanese, and a spine pointing at a file that is not there. The ebook cases worth owning.

An EPUB is a zip of contradictions, and readers resolve them differently

The format allows two tables of contents, two ways to obfuscate a font, fixed and reflowable layout in the same vocabulary, and a package document that can reference files it does not contain. Readers disagree at every one of those points, which is why a book that opens perfectly in one app is a blank page in another.

The ebook catalogue is 90 fixtures, and the groups below are the disagreements worth testing.

Two tables of contents, and what happens when they disagree

EPUB 2 used an NCX. EPUB 3 replaced it with a nav document and kept NCX for backward compatibility, so real books carry one, the other, or both.

Four fixtures cover the whole space:

  • epub3-p7-nav-document-only - modern, no NCX.
  • epub3-p7-ncx-only-no-nav-document - legacy shape in an EPUB 3 wrapper.
  • epub3-p7-nav-and-ncx-dual - both, agreeing.
  • epub3-p7-nav-ncx-mismatch - both, disagreeing.

The last one is the test. A reader must pick one and be consistent, and whichever it picks, the user sees a contents list that does not match the other. Readers that merge the two produce duplicate entries. There is no correct answer the specification enforces, which is exactly why you want to know what your reader does before a user tells you.

epub3-p7-nested-nav-four-levels and epub3-p7-nested-ncx-four-levels push depth, because many readers silently flatten below level two, and epub3-p7-page-list-navigation covers page-number navigation, which matters for citation in academic use.

Fonts that are deliberately scrambled

Embedded font obfuscation exists so publishers can embed licensed faces without shipping a usable font file. There are two incompatible algorithms, and a book can declare neither:

  • epub3-p7-embedded-font-plain - not obfuscated.
  • epub3-p7-embedded-font-idpf-obfuscated - the IDPF algorithm.
  • epub3-p7-embedded-font-adobe-obfuscated - Adobe's, which predates it.
  • epub3-p7-embedded-font-undeclared-obfuscation - obfuscated, and the package does not say so.

The failure is quiet and total: an obfuscated font that a reader does not de-obfuscate is not a broken font, it is random bytes, and the text falls back to a system face. The book renders. It just is not the book the publisher made. The undeclared fixture is the one that catches readers which trust the declaration rather than sniffing the bytes.

Broken packages, where the error message is the product

Five fixtures are deliberately invalid, each in a different place:

  • epub3-p7-unresolved-spine-idref - the reading order names an id that does not exist.
  • epub3-p7-manifest-missing-file - the manifest lists a file the zip does not contain.
  • epub3-p7-manifest-wrong-media-type - a file declared as the wrong type.
  • epub3-p7-manifest-duplicate-id - two entries claiming one id.
  • epub3-p7-container-no-rootfile - the container does not point at a package document.

A reader has three honest options for each: refuse with a clear reason, recover and tell the user what was skipped, or recover silently. The third is the one worth finding, because a book that silently loses a chapter is indistinguishable from a book that never had it.

epub-intentionally-invalid sits alongside epub-valid-reader as the labelled pair, so you can assert that your validator disagrees between the two rather than merely accepting both.

Writing modes, which are not decoration

  • epub3-p7-rtl-arabic-page-progression and epub3-p7-rtl-hebrew. Page progression direction changes which way pages turn. A reader that renders the text right-to-left but still turns pages left-to-right has made the book unreadable in a way that looks almost right.
  • epub3-p7-vertical-writing-japanese - vertical writing mode, where line breaking, furigana and the whole pagination model change.
  • epub3-p7-mixed-bidi-runs - Latin inside Arabic, which is where bidi reordering bugs live.

Fixed layout versus reflowable

epub3-p7-fixed-layout-pre-paginated and epub3-p7-reflowable-twin are the same content in both models, which is what makes them useful: the same book, and the reader must treat them completely differently. epub3-p7-fixed-layout-spread-landscape and -orientation-lock cover spread behaviour, and epub3-p7-fixed-layout-missing-viewport is the common authoring error where a fixed-layout document never states its dimensions, leaving the reader to guess.

Media overlays, for read-along audio

epub3-p7-media-overlay-single-track, -multi-track, -no-duration and -broken-textref.

The last two are the interesting ones. A missing duration means the reader cannot build a timeline without parsing the audio itself, and a broken text reference means the highlight points at nothing while the audio plays on. Both present as "the read-along is out of sync" rather than as an error.

Encoding, in the metadata specifically

epub3-p7-metadata-utf8-diacritics, -numeric-character-references, -utf16-package-document, -astral-plane-characters and -bom-on-every-part.

Metadata encoding is worth separating from content encoding because it is what appears in a library list. A UTF-16 package document is legal and rare enough that many parsers assume UTF-8, and astral-plane characters break any code still treating a JavaScript string index as a character.

Beyond EPUB

mobi-kindle-reader and azw3-kindle-reader for Kindle formats, cbz-comic-archive for comics (a zip of images, where page order is filename order and sorting 10.jpg before 2.jpg is the classic bug), and the FB2 group including fb2-p7-windows-1251-encoded, which is a reminder that not every ebook is UTF-8.

The converter-twins group - epub2-p7-same-book-three-ways, epub3-p7-same-book-three-ways, fb2-p7-same-book-three-ways - is for conversion testing specifically: the same book expressed three ways, so a converter's output can be compared against a known-good sibling rather than judged on its own.

Where to start

  1. epub3-p7-nav-ncx-mismatch, to learn what your reader believes.
  2. epub3-p7-embedded-font-undeclared-obfuscation, because the failure is invisible.
  3. epub3-p7-manifest-missing-file, to see whether a lost chapter is reported.
  4. epub3-p7-rtl-arabic-page-progression, if you ship to any RTL locale.
  5. epub-valid-reader and epub-intentionally-invalid as the pair your validator must separate.

Continue this workflow

Try the workflow

Documentation and troubleshooting

Was this article helpful?

Found an error? Send a correction.