· via dev.to (home feed)
Nx 23 drops bucket cache plugins: what to know before moving to the self-hosted HTTP cache
Nx deprecated its S3, GCS, Azure and shared-FS cache plugins after the CREEP flaw, pushing teams toward a self-hosted HTTP cache. Tests on Nx 23.2.1 show four behaviors worth checking first.

What changed
Nx has removed the old ways of wiring up a custom remote cache. Custom task runners configured through tasksRunnerOptions stopped executing as of Nx 21, and in May 2026 Nx deprecated its own bucket plugins — @nx/s3-cache, @nx/gcs-cache, @nx/azure-cache and @nx/shared-fs-cache — according to a dev.to post by the team behind Cachely, a hosted cache provider. The deprecation is tied to CREEP (CVE-2025-36852), a cache-poisoning vulnerability in which a build from a pull request could overwrite artifacts that a main-branch build would later restore.
For teams that do not want to use Nx Cloud, the sanctioned replacement is the self-hosted HTTP remote cache introduced in Nx 20.8. It requires two environment variables — NX_SELF_HOSTED_REMOTE_CACHE_SERVER and NX_SELF_HOSTED_REMOTE_CACHE_ACCESS_TOKEN — and any server that implements Nx's published OpenAPI specification.
The Cachely team tested the setup on Nx 23.2.1 and reported four behaviors teams should understand before switching.
Copying .nx/cache between CI runs no longer works
A common free workaround was to persist the .nx/cache directory between CI runs using GitHub's actions/cache or Azure's Cache@2, combined with NX_REJECT_UNKNOWN_LOCAL_CACHE=0. That trick is dead. Since the database-backed cache became the default in Nx 20 — and the only option in Nx 21 — Nx refuses to restore artifacts unless it also has the matching metadata, which does not live in .nx/cache. Restoring the folder onto a fresh runner produces an unrecognized-artifacts warning and zero cache hits, and the NX_REJECT_UNKNOWN_LOCAL_CACHE setting is ignored.
An unreachable cache server fails the build
If the URL in NX_SELF_HOSTED_REMOTE_CACHE_SERVER points at a closed port, Nx exits with status 1 and reports a failed request to the /v1/cache endpoint before the task even runs. Teams whose cache server is not guaranteed to be available should probe it first: the post suggests a short-timeout HTTP request to the cache endpoint, and if no HTTP status comes back at all, setting NX_SKIP_REMOTE_CACHE=true to fall back to local caching. Any status code, including a 404 for a deliberately bogus hash, indicates the server is alive. The authors note they only tested a server that was down at the start of a run, not one that dies mid-run.
The skip flags are not interchangeable
Two similarly named flags do different things. --skip-remote-cache, or NX_SKIP_REMOTE_CACHE=true, available since Nx 20.5, disables only the remote cache; Nx announces that remote caching is off and still consults the local cache. --skip-nx-cache, or NX_SKIP_NX_CACHE=true, bypasses both local and remote caches and forces everything to rerun. Separately, nx reset only ever clears the local cache — nothing in the Nx CLI deletes entries from a remote server, so cache lifetime on the server side is the operator's problem.
The server must refuse overwrites
The self-hosted API surface is minimal: GET and PUT on /v1/cache/{hash}. What matters is how PUT behaves on collision. A conforming server must return 409 when a PUT targets a hash that already exists, and 403 for a read-only token. That immutability is the actual fix for CREEP: it prevents a pull-request build from replacing an artifact that a later main build would trust. The post's authors advise anyone running their own server to test both the 409 and 403 paths before relying on it. Nx documents the full specification for building a compliant server in its self-hosted caching guide.
Why it matters
This is a breaking change that arrives through deprecation rather than removal, which makes it easy to miss until a pipeline slows down or a plugin stops working. Teams currently persisting .nx/cache in CI are silently losing all remote-cache benefits already, because the database cache ignores restored files it has no metadata for. Beyond the migration itself, the security model has shifted: correctness now depends on the cache server enforcing immutability, so self-hosting means owning that guarantee. Note that the source post was written by Cachely, which sells a hosted implementation of this spec and therefore has a commercial interest in teams migrating — the technical claims about Nx behaviour are independently testable, but the framing is not neutral.
- #nx
- #monorepo
- #build-cache
- #ci-cd
- #developer-tools
- #remote-cache