An EPUB is a zip file containing XHTML, CSS, images and a couple of XML manifests describing the whole thing. Almost every rejection is one of those manifests disagreeing with what is actually in the zip.
That is good news, because it means the errors are mechanical and the validator can tell you exactly which line is wrong.
Run the validator first
EPUBCheck is the reference validator from the W3C, and it is what the stores run on ingestion. Running it yourself turns a two-day rejection cycle into a thirty-second one.
# Java jar, from the EPUBCheck releases page
java -jar epubcheck.jar book.epub
# Or via a package manager
brew install epubcheck
epubcheck book.epubThere is also a web version if you would rather not install anything, though for an unpublished manuscript think about whether you want to upload it. Output looks like this:
ERROR(RSC-005): book.epub/OEBPS/content.opf(12,45):
Error while parsing file: element "dc:title" not allowed here
WARNING(ACC-007): book.epub/OEBPS/ch01.xhtml(48,3):
The "img" element should have an accessible nameRead it as: severity(code): file(line,column): message. The code is worth pasting into a search — every one of them is documented, and the documentation is better than the message.
The errors that actually block you
| Code | What it means | Usual cause |
|---|---|---|
RSC-001 | A file the manifest lists is missing | An image deleted after the manifest was written |
RSC-007 | A referenced resource cannot be found | A broken src or href |
OPF-003 | A file in the zip is not in the manifest | An asset added by hand |
RSC-005 | The XML or XHTML is invalid | An unclosed tag, or a bare & |
OPF-030 | No unique identifier | Missing dc:identifier, or the unique-identifier attribute not pointing at it |
PKG-006 | The mimetype file is wrong | Rezipped with a normal zip tool |
RSC-006 | A remote resource is referenced | A font or image left on a CDN |
NAV-001 | The navigation document is missing or malformed | No nav doc, or a toc without a nav |
Three of those deserve a note.
`PKG-006` catches almost everyone who has ever unzipped an EPUB, edited a file and zipped it back up. The spec requires the mimetype file to be the first entry in the archive and stored uncompressed. Ordinary zip tools do neither.
cd unpacked/
zip -X0 ../book.epub mimetype
zip -Xr9D ../book.epub . -x mimetype`RSC-006` — a remote resource — is a real failure rather than a nicety. An EPUB is meant to be self-contained and readable offline; a cover pulled from a URL is a book that breaks on a plane. Every image and font has to be inside the file.
`RSC-005` is the broadest and usually the simplest. EPUB content is XHTML, which is XML, which is strict in ways HTML is not: every tag closes, <br> must be <br/>, attributes are quoted, and a bare ampersand is an error. Anything hand-edited or pasted from a web page hits this.
Warnings you can and cannot ignore
- **Accessibility warnings (
ACC-*).** Images with no alt text, missing language, poor heading structure. EPUBCheck warns; the EU Accessibility Act means several stores and retailers now treat missing accessibility metadata as a reason to reject. Fix them. - **
HTM-*style warnings.** Usually advisory — an empty element, a deprecated attribute. Safe to leave. - Fonts that are not obfuscated. Only relevant if your licence requires it; the format does not.
- Unused declarations in the manifest. Untidy, harmless.
Store-specific rejections that pass validation
A clean EPUBCheck run is necessary and not sufficient. Each store adds its own rules on top:
- Apple Books is the strictest on metadata and on cover images, and it rejects files that validate elsewhere.
- Amazon KDP converts your EPUB to its own format, so its complaints are about what survives conversion — deeply nested tables, unusual CSS, fixed positioning.
- Kobo and Google Play are comparatively permissive and will surface layout oddities rather than block ingestion.
- Every store dislikes a table of contents typed by hand with page numbers in it. The navigation has to come from the document's structure. Page numbers in a reflowable file are meaningless anyway — see EPUB or PDF.
The fix that avoids all of this
Every error in the table above is a hand-assembly error. They come from unzipping an EPUB to change something, from an exporter that writes a manifest loosely, or from a conversion chain with one step too many.
A file generated from a structured source does not have them, because nothing ever gets out of step: the manifest is written from the same content in the same pass. Exporting an EPUB from bukpress produces a file whose structure comes from your headings, with the fonts packaged in and the cover set as the file's own cover image — which is the list of things RSC-006, OPF-003 and NAV-001 are complaining about when they fire.
If you do end up editing an EPUB by hand — and sometimes there is no way around it — validate after every change rather than at the end. The error messages are precise; a stack of twelve of them from a session of edits is much harder to read than one at a time.