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

  1. Rebuild the artifact: re-run deno compile from a clean checkout and redistribute.
  2. Delete the cached copy (DENO_DIR npm cache / the downloaded binary) and re-download from the original source.
  3. Verify integrity before running: compare size and sha256 against the value recorded at build time.
  4. 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

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

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/00fab1b9e1c3e1f3. Report an issue: GitHub.