Question and suitable scenarios
You own an API gateway that may filter malicious attachments, remove private fields, or transcode a response. The origin request succeeds, but the downstream representation is no longer the origin’s bytes. Explain when to return 203, how to handle validators, and how to stop clients from treating transformed data as authoritative origin data.
HTTP 203 is a successful response indicating that a transforming proxy changed headers or content from the origin’s 200 response. It is a protocol signal for “successful, but transformed,” not a generic error or authorization status.
What the interviewer is testing
- Accurate boundaries between 203, 200, 304, 4xx, and 5xx.
- Understanding how transformation affects caches, ETags, signatures, and later requests.
- A traceable audit link between origin and downstream representations.
- Handling multiple proxies, origin failures, and clients that do not understand 203.
- Turning protocol semantics into testable headers and cache behavior.
Clarifications before answering
- Is the change malware filtering, transcoding, or user-specific redaction? This affects cache sharing.
- Can clients recognize 203? If not, is a compatibility layer required?
- Must the original representation be traceable? Signatures and audit records need both versions.
- Is the transformation deterministic? If rules vary, the rule version belongs in the cache key.
A 30-second answer framework
First I verify whether the gateway changed application content or relevant headers. A successful origin response with an altered representation gets 203; an untouched representation stays 200. 203 does not replace 304, which only validates a client’s existing representation. I generate an ETag for the downstream representation and include content negotiation, rule version, and tenant boundaries in the cache key. Audit records link the origin version to the transformed output. Origin failures keep their actual failure semantics.
Step-by-step deep answer
1. Establish status-code boundaries
200 says the current response succeeded without declaring an application transformation. 203 says the request succeeded but a transforming proxy changed headers or content from the origin’s 200. 304 carries no new representation and asks the client to reuse a validated one. Filtering failure, refusal, and origin timeout use their appropriate 4xx or 5xx semantics.
2. Classify the transformation
Replacing a malware-blocked URL, privacy filtering, format transcoding, and mirror metadata can justify 203. Changing only transfer compression or hop-by-hop fields normally does not change the application representation. The gateway should record what changed and why.
3. Recompute validators
An origin ETag describes the origin representation. The transformed output needs a downstream ETag that is valid for that output. If a rule version changes bytes, include it in the cache key or validator input; otherwise a rule rollout can reuse stale output.
4. Design caching and negotiation
Vary, content encoding, language, tenant, and transformation rule all affect shareability. Default privacy-sensitive results to private caching; share only deterministic public transformations. For If-None-Match, validate the gateway’s representation rather than forwarding an origin 304 for bytes the client does not have.
5. Protect signatures and audit trails
An origin signature over original bytes cannot prove a modified downstream body. Re-sign the transformed representation or remove the invalid signature. Log the origin request ID, origin ETag, rule version, output ETag, and transformation reason.
6. Handle multiple proxies
Each layer should preserve transformation provenance and avoid repeating a non-idempotent rule. If a client cannot understand 203, an explicit compatibility layer may return 200 with documented metadata, but it must not silently hide a security or privacy transformation.
7. Verify and roll back
Test origin 200, transformed 203, untouched 200, downstream 304, rule rollout, origin timeout, and filter failure. During rollback, ensure old and new ETags cannot collide and inspect shared cache entries created under the old rule.
High-quality sample answer
I treat 203 as the declaration “the request succeeded, but a transforming proxy changed the origin representation.” An untouched application response remains 200; a transformed one is 203; 304 only validates the downstream representation and cannot be passed through blindly from the origin. The gateway creates a new ETag for the transformed bytes and keys caching by rule version, negotiation, and privacy boundary. If the origin signature covered original bytes, the gateway re-signs or removes it. Tests cover 200/203/304, rule changes, proxy chains, and origin failures so clients never mistake filtered data for origin data.
Common mistakes
- Return 203 for every proxy response → semantics become noisy → use it only for a real representation change.
- Reuse the origin ETag → validators describe the wrong bytes → generate one for the downstream output.
- Treat 203 as an error → clients may retry or alert → preserve the actual 4xx/5xx failure semantics.
- Forward an origin 304 blindly → the transformed cache may not be valid → validate the downstream representation.
- Ignore rule versions → rollouts can serve old output → include the version in keys or validators.
Follow-up questions and responses
Does changing only Content-Encoding require 203?
Usually no. Transfer encoding is transport handling; if the application representation is unchanged, keep 200 and apply normal negotiation rules.
Can a 203 response be shared by a cache?
Yes, if the transformation is deterministic, every varying dimension is keyed, and no user-private data is present. Tenant-specific output should be private.
What if an origin 203 is transformed again by the gateway?
Preserve both provenance links, compute a final ETag, and verify idempotence. If idempotence is not guaranteed, allow only one transformation.
Can a compatibility layer turn 203 into 200?
It can when explicitly documented, with detectable metadata and audit logging. It must not silently conceal security filtering or privacy redaction.
What if the origin returns 304 but no transformed object exists locally?
Do not return 304 directly. Fetch a usable representation and transform it, or return a failure that reflects the missing local representation.