Skip to content
Control Plane Labs

226 IM Used

Success response defined by RFC 3229 §10.4.1.

Last updated July 27, 2026

Common causes at a glance

  • A feed or document server implementing RFC 3229 delta encoding
  • A client sending A-IM with a manipulation the server supports
  • An RSS or Atom aggregator negotiating deltas against a large feed
  • An internal sync protocol reusing 226 for its own diff format

Reproduce it

curl -i -H 'A-IM: vcdiff' -H 'If-None-Match: "abc123"' https://www.example.com/feed.xml

What 226 IM Used means

Delta encoding tried to make conditional requests cheaper than all-or-nothing. Instead of a 304 with no data or a 200 with the whole document, the client advertises acceptable manipulations via A-IM and names the version it holds with If-None-Match. If the resource changed, the server diffs against that version and returns 226 with just the diff.

For a large document with small frequent changes — the motivating example was RSS feeds — the saving is dramatic. It never took off because the server must retain every recent version to diff against, and gzip plus a sensible caching policy gets most of the benefit.

What the spec says

RFC 3229 §10.4.1 defines 226. The mechanism needs three header fields, all in §10.5: A-IM in the request listing acceptable instance-manipulations, IM in the response naming those applied, and Delta-Base identifying the entity tag of the base instance. §10.3 sets the preconditions: the server must be willing to send a 200, and the request must carry both A-IM and If-None-Match. Caching gets its own treatment in §10.6, because a cache that does not understand the listed manipulations must not serve the stored response. RFC 3229 is Proposed Standard and was never widely implemented.

What actually causes it

Realistically you will never see 226 on the public internet. A handful of feed servers implemented A-IM: feed, a variant returning only new entries in an Atom or RSS document, and a few blog platforms still carry it from an old plugin. Beyond that, delta encoding lost to compression. The operational demand is the killer: to diff against whatever version an arbitrary client holds, the origin needs a history of representations keyed by entity tag, expensive to keep and awkward to shard across a CDN. A cache that does not understand the manipulation named in IM must not reuse the response, making a 226 uncacheable at the edge.

How to debug it

Probe with both required request fields and see what comes back:

etag=$(curl -sI https://www.example.com/feed.xml | awk 'tolower($1)=="etag:"{print $2}' | tr -d '\r')
curl -sD - -o /dev/null -H 'A-IM: feed, vcdiff' -H "If-None-Match: $etag" https://www.example.com/feed.xml

A server that does not implement RFC 3229 ignores A-IM and answers 304 if the tag matches or 200 if it does not, which is the outcome essentially everywhere. A real 226 carries an IM header naming the applied manipulation and a Delta-Base giving the base entity tag. If Delta-Base is missing or names a version you do not hold, refetch without A-IM. No mainstream library applies deltas for you.

Working examples

curl

# Both A-IM and If-None-Match are required for a 226 to be legal.
curl -i \
  -H 'A-IM: feed, vcdiff' \
  -H 'If-None-Match: "abc123"' \
  https://www.example.com/feed.xml

# A 226 response looks like:
#   HTTP/1.1 226 IM Used
#   IM: vcdiff
#   Delta-Base: "abc123"
#   ETag: "def456"
# Anything else means delta encoding is not implemented; expect 200 or 304.

Python (requests)

import requests

url = "https://www.example.com/feed.xml"
etag = requests.head(url, timeout=10).headers.get("ETag")

resp = requests.get(
    url,
    headers={"A-IM": "feed, vcdiff", "If-None-Match": etag},
    timeout=10,
)
print(resp.status_code)  # realistically 304 or 200; 226 is vanishingly rare

if resp.status_code == 226:
    print("applied:", resp.headers.get("IM"))
    print("base:", resp.headers.get("Delta-Base"))
    # requests hands back the raw delta. Applying it is entirely on you.
    delta = resp.content
    print(len(delta), "bytes of diff against the base instance")

Node (fetch)

const url = "https://www.example.com/feed.xml";
const head = await fetch(url, { method: "HEAD" });

const res = await fetch(url, {
  headers: { "A-IM": "feed, vcdiff", "If-None-Match": head.headers.get("etag") },
});

console.log(res.status, res.headers.get("im"), res.headers.get("delta-base"));

if (res.status === 226) {
  // fetch() returns the delta bytes untouched; there is no built-in patcher.
  const delta = await res.arrayBuffer();
  console.warn("delta of", delta.byteLength, "bytes - apply it yourself");
} else {
  console.log("no delta encoding here; got a plain", res.status);
}

Reference and tooling

The authoritative list of assigned status codes is theIANA HTTP Status Code Registry. For a searchable copy with the semantics summarised, use theHTTP status code reference on this site. To see exactly what a server is sending, theheader inspector shows the raw status line and response headers, and thecurl builder assembles the request flags for you.

Other 2xx codes