Backend interview: How would you design an HTTP 415 Unsupported Media Type contract?
Prompt and scope
An API accepts JSON and CBOR for POST and JSON Patch for PATCH. Clients receive 415 after sending the wrong Content-Type, content encoding, or patch-document format. Design server classification, response headers, error body, client recovery, and version evolution.
This is a backend API contract question. The media types and formats are assumptions, not frequency claims.
What the interviewer is testing
- Whether you separate request Content-Type and Content-Encoding from response Accept.
- Whether you use 415 narrowly instead of labeling every parse error that way.
- Whether you expose PATCH capability with Accept-Patch while preserving compatibility.
- Whether the error is actionable without unsafe automatic replay.
Clarifying questions to ask
- Is 415 caused by media type, content encoding, or method capability?
- Can the client re-encode the body, and is there a stable request ID?
- Which patch formats and resource-version conditions are supported?
- Can a gateway rewrite Content-Type, encoding, or the error body?
- How will a new media type roll out without breaking old clients?
A 30-second answer
“415 means the target method refuses the request representation’s format. The server parses Content-Type, parameters, and Content-Encoding, then selects a parser based on method and resource capability. Accept describes the response formats the client wants; it does not describe the patch document it sent. A PATCH resource can advertise supported document types with Accept-Patch. The error returns a stable code, received and allowed values, and a request ID. Retry only after safe re-encoding and replay analysis.”
Step-by-step design
1. Separate the three header semantics
Content-Type describes the request body’s media type, Content-Encoding describes transfer coding, and Accept describes response representations the client can receive. The server must not use Accept to classify a PATCH document or merge decompression, corruption, and unsupported media into one cause.
2. Map method and resource capability
Each method and resource declares supported media types and parameters. For example, POST accepts application/json and application/cbor, while PATCH accepts a registered JSON Patch document type. Check type and encoding before parsing; after parsing, still run schema, authorization, and business validation.
PATCH /documents/42 HTTP/1.1
Content-Type: application/json-patch+json
Accept: application/json
Content-Length: 1283. Return an accurate 415
Return 415 with a stable error code when the media type or content encoding is unsupported. Use a domain validation error for valid syntax with invalid fields, and a clear parse error for malformed content. An Accept response header can describe representations the server can return; it is not a list of request media types.
4. Advertise PATCH capability
RFC 5789 defines Accept-Patch; a resource can declare supported patch-document media types in OPTIONS or a successful response. The client can then choose JSON Patch or another format, while the server still checks resource version, paths, and authorization. The advertisement must match the actual parser set.
5. Make client recovery safe
After 415, the client reads the stable code and allowed type, re-encodes the body, or selects a compatible endpoint. Automatic retry requires a rebuildable body, no irreversible side effect, and the same idempotency key. Do not resubmit a PATCH that may have succeeded, and do not treat 415 as temporary unavailability.
6. Roll out and observe changes
Canary a new media type through gateway, server, and SDK, while retaining a compatibility window for the old type. Segment metrics by resource, method, received type, encoding, client version, and rejection reason. Log request ID and parser version, never sensitive bodies. Compare edge and application headers when a gateway rewrites them.
Model high-quality answer
“I separate request and response formats. The server checks Content-Type and Content-Encoding by method and resource, parses only supported representations, then runs schema and business validation; Accept is for response negotiation. PATCH resources advertise document types with Accept-Patch, but each request still checks version and authorization. A 415 body gives a stable code, received and allowed values, and request ID. Clients retry only after safe re-encoding. New types roll out through a compatibility matrix and metrics so gateways or old SDKs do not silently change semantics.”
Common mistakes
- Using Accept to classify the request body → request and response negotiation are mixed → inspect Content-Type and Content-Encoding.
- Returning 415 for every parse failure → clients cannot choose a repair → separate media, syntax, and domain errors.
- Advertising Accept-Patch without a parser → the capability contract is false → validate the declaration against implementation.
- Retrying the same body after 415 → it will fail or duplicate side effects → change encoding and confirm replay safety.
- Logging the type only in the application → gateway rewrites become invisible → compare headers and request IDs per hop.
Follow-up questions and responses
If Content-Type is valid but Content-Encoding is unsupported, is 415 still correct?
RFC 9110 includes an unacceptable request content coding within 415’s scope. Explain the encoding in the error, then decompress or select a supported encoding before deciding whether the body and operation can be safely retried.
Why not return only a list of allowed types?
A list omits method, parameter, and version constraints. A stable code, received value, allowed scope, request ID, and documentation link make the repair actionable without exposing internals.
How do you add CBOR safely?
Enable it first on noncritical resources, verify gateway pass-through, parser resource limits, schema equivalence, and log redaction. Keep JSON fallback and compare 415, parse failures, and business outcomes by client version.