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.xmlWhat 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.