Skip to content
Latchkey

CircleCI Cache Restored Wrong Arch - Fix Cross-Executor Caches

A cache built on one executor is restored on a different OS/arch, so native binaries no longer match. Sharing a cache key across Linux/macOS, x86/arm, or different runtime versions restores incompatible compiled artifacts.

What this error means

After a cache hit the job fails with "exec format error", a Node/Python ABI mismatch, or a native module that "was compiled against a different version". It only happens on some executors because the cache came from another platform.

job log
Error: Module did not self-register / exec format error
node_modules/.../binding.node: cannot execute binary file
(cache built on linux/amd64, restored on linux/arm64)

Common causes

One cache key shared across architectures

A key without an arch/OS component lets an arm job restore an x86-built cache (or vice versa). Native .node/.so files are not portable.

Cache shared across runtime versions

Native modules are built against a specific Node/Python ABI. Restoring a cache built on a different runtime version yields ABI errors.

Caching compiled node_modules across executors

Caching built node_modules rather than the package manager cache makes the cache platform-specific and fragile across executor types.

How to fix it

Include OS/arch/runtime in the cache key

.circleci/config.yml
- restore_cache:
    keys:
      - deps-v1-{{ arch }}-{{ checksum ".node-version" }}-{{ checksum "package-lock.json" }}
- run: npm ci
- save_cache:
    key: deps-v1-{{ arch }}-{{ checksum ".node-version" }}-{{ checksum "package-lock.json" }}
    paths: [~/.npm]

Cache the package manager cache, not compiled output

  1. Cache ~/.npm / ~/.cache/pip, then reinstall to rebuild native modules per platform.
  2. Add the runtime version to the key so ABI changes invalidate it.
  3. Use distinct key prefixes per executor when caches must differ.

How to prevent it

  • Always include {{ arch }} and the runtime version in cache keys.
  • Cache the package manager cache, not platform-specific compiled modules.
  • Use separate keys per executor type to avoid cross-arch restores.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →