Documentation

Troubleshooting cache errors

Find the symptom, not the tool. Most cache failures are one of four things: a URL with a path appended, a token with the wrong scope, a task that was never cacheable, or environment variables that did not reach the process that needed them.

What the status codes mean

401 Unauthorized
The token is missing, invalid, revoked, or scoped to a different workspace. Generate a new one under your workspace's tokens. A 401 is always about the credential - it never means the artifact is absent.
403 Forbidden on upload
Your token is read-only. Downloads work and uploads are rejected. That is the intended configuration for pull-request and fork builds; use a read-write token for the builds that should populate the cache, typically your protected branches. See tokens and access control.
404 Not Found
Usually just a miss: no artifact exists for that task hash yet, so the build runs the task and (with a read-write token) populates the cache for next time. A 100% 404 rate is different - that is the appended-path mistake below.
409 Conflict
Something tried to overwrite an existing cache key. Managed artifacts are immutable by design, so this is the API refusing to let a known good build be silently replaced. It is safe to ignore in a race between two runners producing the same hash.

Nothing ever hits the cache

Every request 404s (Nx)
NX_SELF_HOSTED_REMOTE_CACHE_SERVER must be the bare host (https://remote.cachely.dev) with no trailing path. Nx appends /v1/cache/<hash> itself, so adding it yourself doubles the path and nothing is ever found. The same rule applies to Gradle's url and Bazel's --remote_cache.
Requests succeed but always miss
Different machines are computing different task hashes. The usual cause is an Nx version mismatch between CI runners and developers - hashes are not comparable across versions, so the cache is technically working and structurally useless. Pin the version. If the versions match, the inputs are drifting instead: the hit-rate guide covers over-keyed inputs, timestamps in outputs, and environment values leaking into the hash.
The task is not cacheable
Nx and Lerna only consult the cache for targets declared cacheable in nx.json ("cache": true). Gradle requires org.gradle.caching=true and a task type that supports output caching.
The variables never reached the build
Environment variables set on one CI step are invisible to the next. Declare them at the workflow or job level. Locally, confirm the shell that runs the build actually exports them - a variable set in a different terminal tab is the most common version of this.

Tool-specific symptoms

Lerna runs but never hits the remote cache
Confirm the task has "cache": true in nx.json, that both Nx environment variables are visible to the lerna process, and that every runner resolves the same Nx version. Lerna delegates cache reads and writes to Nx, so every Nx cause applies unchanged.
Gradle loads but never stores
Loads working while stores are skipped means isPush is false, or the token is read-only. Both are the intended CI-push / developer-read configuration - check whether the build you are looking at is meant to be a writer. A 401 in --info output means the token is wrong or revoked instead.
Gradle never stores or loads anything
Confirm the URL is https://remote.cachely.dev with no path, org.gradle.caching=true is set (or --build-cache is passed), the task is cacheable, and GRADLE_CACHE_TOKEN is exported in the environment Gradle runs in. Run with --info and look for FROM-CACHE.
Bazel never hits the cache
Confirm --remote_cache is the bare host with no path - Bazel appends /ac/ and /cas/ itself. Check the --remote_header token is present and not revoked. Remember the committed .bazelrc in the Bazel setup disables uploads by default, so a workspace where only developers build will stay empty until trusted CI runs with --config=cachely-ci.

The dashboard shows no activity

Either no cache requests have arrived in the selected time range, or the token used belongs to a different workspace than the one you are viewing. Widen the range first - it is the cheaper check. If a full CI pipeline produced nothing at all, the variables did not reach the build; see CI setup.

Still stuck

Ask in the Cachely Discord - someone has usually hit the same status code - or email hello@cachely.dev with the build tool and version, the status code you are seeing, and whether the token is read-only or read-write. Either way, do not post or send cache artifacts or build logs containing your source paths - we do not need them and do not want them, and Discord is a public channel.

Get back to fast builds
Most of these are a one-line fix. The dashboard shows whether it worked.
Start freeSee pricing