evanw/esbuild · critical · Error

Cannot start service: Host version

Error message

Cannot start service: Host version "${ESBUILD_VERSION}" does not match binary version ${quote(binaryVersion)}

What it means

On the first packet from the spawned esbuild binary, the JS wrapper compares the binary's self-reported version against the JS-side ESBUILD_VERSION constant (lib/shared/common.ts:622). Any mismatch aborts service startup. This guard detects broken installs where the native binary (from a platform package like @esbuild/linux-x64) and the JS wrapper come from different esbuild releases.

Solutions

  1. Delete node_modules and the lockfile, then reinstall cleanly so esbuild and all @esbuild/* platform packages align to one version.
  2. Run your package manager's dedupe (npm dedupe / yarn dedupe / pnpm dedupe) to collapse duplicate esbuild versions.
  3. Pin esbuild to a single exact version in package.json and ensure transitive deps don't pull in a different one (npm ls esbuild).
  4. Clear CI caches that snapshot node_modules across version bumps.

Example fix

# before: mismatched versions in lockfile
npm ls esbuild      # shows multiple versions

# after
rm -rf node_modules package-lock.json
npm install esbuild@latest
npm ls esbuild      # single version
Defensive patterns

Strategy: try-catch

Validate before calling

import { version as jsVersion } from 'esbuild'
// Fail fast in your own setup if a platform binary is missing/mismatched
import { existsSync } from 'fs'
// Example: sanity-check that the platform package resolves
function preflight() {
  try {
    require.resolve('@esbuild/linux-x64/bin/esbuild') // adjust to your platform
  } catch {
    throw new Error('esbuild platform binary not installed; run a clean install')
  }
}
preflight()

Try / catch

try {
  await esbuild.build(opts)
} catch (e) {
  if (/does not match binary version/.test(e.message)) {
    console.error('esbuild version mismatch detected. Run: rm -rf node_modules package-lock.json && npm install')
    process.exit(1)
  }
  throw e
}

Prevention

When it happens

Trigger: Any esbuild API call (build/transform/context) that starts the service when the installed `esbuild` JS package version differs from the installed platform-binary package version. The message prints both versions for diagnosis.

Common situations: A partial/half-upgraded install (lockfile resolved esbuild to one version and @esbuild/<platform> to another); duplicate esbuild copies in a monorepo (hoisting); stale npm/yarn/pnpm cache or PnP mismatch; manually copied esbuild binaries; CI caching node_modules across an upgrade.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/0b3f6d50902caaf5. Report an issue: GitHub.

Appendix: source

Thrown at lib/shared/common.ts:623

        // cause an unhandled promise rejection. Our caller isn't expecting
        // this call to fail and doesn't handle the promise rejection.
      }
    }
  }

  let isFirstPacket = true

  let handleIncomingPacket = (bytes: Uint8Array<ArrayBuffer>): void => {
    // The first packet is a version check
    if (isFirstPacket) {
      isFirstPacket = false

      // Validate the binary's version number to make sure esbuild was installed
      // correctly. This check was added because some people have reported
      // errors that appear to indicate an incorrect installation.
      let binaryVersion = String.fromCharCode(...bytes)
      if (binaryVersion !== ESBUILD_VERSION) {
        throw new Error(`Cannot start service: Host version "${ESBUILD_VERSION}" does not match binary version ${quote(binaryVersion)}`)
      }
      return
    }

    let packet = protocol.decodePacket(bytes) as any

    if (packet.isRequest) {
      handleRequest(packet.id, packet.value)
    }

    else {
      let callback = responseCallbacks[packet.id]!
      delete responseCallbacks[packet.id]
      if (packet.value.error) callback(packet.value.error, {})
      else callback(null, packet.value)
    }
  }

View on GitHub (pinned to f6058f8364)