Skip to content
Latchkey

Fastly surrogate-key purge succeeds but has no effect in CI

The purge API returned success but stale content persists: a surrogate-key purge only clears objects that were cached with a matching Surrogate-Key response header. If origin never set that header, there is nothing to match, so the purge is a no-op.

What this error means

The purge-by-key call returns HTTP 200 with "status": "ok", yet the edge keeps serving the old asset. Only purge-all or a single-URL purge actually clears it.

Fastly API
{ "status": "ok", "id": "1234-5678" }
# HTTP 200, but old content still served: objects carry no matching Surrogate-Key

Common causes

Origin never sends a Surrogate-Key header

Objects cached without a Surrogate-Key response header have no tag to purge by, so a key purge matches nothing even though the API accepts it.

The purge key does not match the tag

The key sent to the purge endpoint differs from the value origin set (case, prefix, or a different tag), so no cached object is selected.

How to fix it

Tag responses with Surrogate-Key at origin

  1. Emit a Surrogate-Key response header on cacheable objects.
  2. Purge using the exact key value origin sets.
  3. Confirm the header is present on a cached response before relying on key purges.
HTTP response header
# origin (or VCL) sets a key on the response
Surrogate-Key: release-2026-06-30 static-assets

Verify by inspecting a cached response

Fetch an object and confirm it carries the surrogate key you intend to purge.

Terminal
curl -sI "https://www.example.com/app.js" | grep -i surrogate-key

How to prevent it

  • Always set Surrogate-Key on cacheable responses you plan to purge by key.
  • Purge with the exact key origin emits.
  • Fall back to single-URL or purge-all when a key is not present.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →