denoland/deno · error
invalid utf-8 data
Error message
invalid utf-8 data
What it means
eszip v2 parser (used by deno compile artifacts and cached npm sections): npm dependency entries carry length-prefixed strings; parse_string converts the bytes with String::from_utf8. If the byte slice is not valid UTF-8, parsing aborts with ErrorKind::InvalidData and this message — the archive's npm section is corrupt.
Source
Thrown at libs/eszip/v2.rs:1882
))
}
}
struct EszipNpmDependency(String, EszipNpmPackageIndex);
impl EszipNpmDependency {
pub fn parse(input: &[u8]) -> std::io::Result<(&[u8], Self)> {
let (input, name) = parse_string(input)?;
let (input, pkg_index) = EszipNpmPackageIndex::parse(input)?;
Ok((input, EszipNpmDependency(name, pkg_index)))
}
}
fn parse_string(input: &[u8]) -> std::io::Result<(&[u8], String)> {
let (input, size) = parse_u32(input)?;
let (input, name) = move_bytes(input, size as usize)?;
let text = String::from_utf8(name.to_vec()).map_err(|_| {
std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid utf-8 data")
})?;
Ok((input, text))
}
fn parse_u32(input: &[u8]) -> std::io::Result<(&[u8], u32)> {
let (input, value_bytes) = move_bytes(input, 4)?;
let value = u32::from_be_bytes(value_bytes.try_into().unwrap());
Ok((input, value))
}
fn move_bytes(
bytes: &[u8],
len: usize,
) -> Result<(&[u8], &[u8]), std::io::Error> {
if bytes.len() < len {
Err(std::io::Error::new(
std::io::ErrorKind::UnexpectedEof,
"unexpected end of bytes",View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Rebuild the artifact: re-run deno compile from a clean checkout and redistribute.
- Delete the cached copy (DENO_DIR npm cache / the downloaded binary) and re-download from the original source.
- Verify integrity before running: compare size and sha256 against the value recorded at build time.
- Check for disk-full or interrupted-write conditions on the machine that produced the artifact.
Example fix
# before deno run --cached-only app.ts # corrupt eszip in cache -> invalid utf-8 data # after deno clean # or: rm -rf "$DENO_DIR/npm" deno cache main.ts && deno run app.ts # for compiled binaries: re-run `deno compile` and replace the artifact
Defensive patterns
Strategy: fallback
Validate before calling
import { createHash } from "node:crypto";
import { readFile } from "node:fs/promises";
async function verify(artifact, expectedSha) {
const actual = createHash("sha256").update(await readFile(artifact)).digest("hex");
if (actual !== expectedSha) throw new Error(`artifact corrupt (sha mismatch): ${artifact}`);
} Try / catch
try { await run(); } catch (e) { if (/invalid utf-8 data/.test(String(e))) { await rebuildArtifact(); /* recompile/redownload then retry */ } else throw e; } Prevention
- Record size+sha256 of deno compile artifacts at build time and verify before every run.
- Do not resume interrupted downloads of eszip-bearing files; restart them atomically (write to temp, rename).
- Keep CI cache keys content-addressed so corrupt cache entries are never reused.
When it happens
Trigger: Loading an eszip (compiled binary or cached npm section) whose dependency-name bytes were corrupted: bit rot, truncated then re-padded download, partial write during creation, or mutation by transfer/patching tools.
Common situations: deno compile artifacts corrupted in artifact storage or CI caching; interrupted downloads resumed incorrectly; npm cache eszip files corrupted after disk-full events; files mangled by text-mode transfer (FTP/editor).
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unexpected end of bytes
- invalid module type
- missing index '{}'
- Unexpected 'fn' field in options, bench function is already
- failed to validate startup order {}: {error}
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/00fab1b9e1c3e1f3.
Report an issue: GitHub.