Summary

  • digest-mismatched-values reports that one responding server calculated a different digest for a named field. It does not identify the actor that changed the bytes, reveal the server's calculated value, or prove whether the application committed work.
  • The draft says a sender might have been affected by an intermediary and could retry for a temporary transmission problem. For a non-idempotent request, RFC 9110 still requires independent knowledge that replay is safe; a typed problem is not that authority.

The first POST timed out at the application boundary but eventually returned a 400 response. Its body named digest-mismatched-values, identified Content-Digest, and repeated the digest the client had supplied. An automation rule read the response as a complete story: an intermediary had corrupted the body, the origin had rejected it before doing any work, and the correct remedy was to send the same POST again.

The customer received two orders.

Nothing in the proposed problem type licensed the three inferences that produced the second one. The response said that a validation calculation disagreed. The Internet-Draft notes that the request might have been unintentionally modified by an intermediary and that a sender could retry an unchanged request when the cause is a temporary transmission issue. “Might” is not attribution. “Could” is not an instruction. Most importantly, a digest comparison is not an application-commit receipt.

That boundary is the practical value of HTTP Problem Types for Digest Fields. Revision 06, dated 24 June 2026 and expiring 26 December 2026, defines machine-readable ways to distinguish unsupported algorithms, invalid digest values and mismatched values. At the research cut-off on 2 October 2026, Datatracker placed the HTTPAPI working-group draft in the RFC Editor queue, awaiting a first editor, with Mike Bishop as responsible Area Director and IANA actions acknowledged. It is intended for the Standards Track as a Proposed Standard, but no RFC number has been assigned. Queue position is documentary maturity, not evidence that a particular gateway implements the draft.

Three errors that should not share one button

The draft proposes three problem types, each with recommended status 400. digest-unsupported-algorithms says the validator does not support any algorithm supplied for the relevant field. Its unsupported_algorithms entries name the algorithm and header. A response may include a corresponding preference field so that the server can indicate supported choices and their preference.

That is a capability hint. It may justify constructing another request with a supported algorithm. It does not promise that the next request will pass authorization, conditional checks, quota, business validation or transaction admission. Changing SHA-256 to a supported alternative can resolve one validator decision while leaving every application decision untouched.

digest-invalid-values is different. It describes a value that cannot have been generated by its named algorithm—for example, a SHA-512 digest with an impossible byte length. Its entries can include a human-readable reason. Repeating the same malformed value is likely to reproduce the same failure because the defect lies in calculation or encoding.

This type is not used merely because the field failed Structured Fields parsing. Syntax failure happens before the validator has a usable algorithm/value pair. An impossible value and an unparseable field are different states, with different owners and remediation. A dashboard that calls both “checksum error” throws away the distinction the draft created.

digest-mismatched-values begins later. The value is sufficiently well formed to compare, but it does not equal what the server calculated for the named scope. The response can identify the algorithm, the provided digest and the header. It cannot establish whether the sender hashed the wrong bytes, a content coding changed the representation, an intermediary transformed the message, corruption occurred, or the endpoints disagree about scope.

Machine-readable precision should narrow the next action. It should not make the causal story sound more certain than the comparison.

The header name is part of the fact

RFC 9530 distinguishes Content-Digest from Repr-Digest. The former is calculated over HTTP content. The latter concerns the selected representation. Content codings and transformations can make those byte domains different. The related active Unencoded-Digest Internet-Draft introduces another scope for unencoded content; it is not an RFC at this cut-off.

This is why each diagnostic entry contains header. An observability system that retains only algorithm=sha-256 and mismatch=true has lost the layer being compared. It may faithfully store the number while falsifying its meaning.

Suppose a sender calculates the digest before content coding, a gateway validates after coding, and the origin validates a representation after another transformation. Each component can calculate a correct digest for the bytes it actually sees. Their values can still disagree because their scopes differ. “The hash is wrong” is then a category error. The missing question is: wrong for which named field, at which hop, over which bytes?

The same discipline applies to the response. RFC 9457 makes a problem type a class of error and permits extension members to carry details. It does not let that body redefine HTTP status semantics. If a status member appears in the JSON, it is advisory and can disagree with the actual status after intermediary handling. The transport response and the problem body are related observations, not one indivisible verdict.

The missing digest is an intentional limit

For a mismatch, the draft allows the server to repeat provided_digest. It deliberately does not return the digest the server calculated. No method in the specification communicates that value because doing so could create an oracle.

That omission is protective, but it also defines the evidence ceiling. The client cannot use the problem response as a reconciliation transcript. It knows that a comparison failed. It does not know the server's result, the precise byte sequence used, or the component that introduced the difference.

Detailed errors have their own exposure surface. They can reveal which algorithms or fields a server supports, disclose whether intermediaries participate in validation, and help fingerprint implementation behavior. The echoed provided value may also be sensitive when copied into traces, tickets and third-party analytics. A production record can retain a safe fingerprint and protected raw evidence without broadcasting the original value to every observability consumer.

Optionality adds another limit. The extension arrays are optional, and their omission has no special meaning. Clients generally cannot rely on a server returning every diagnostic field. Multiple Digest or preference fields can produce multiple entries. The first array item is not necessarily the only fault or the preferred remediation. Array order is not an authorization policy.

Response received is not operation uncommitted

In a simple origin, digest validation may happen before application code. Distributed systems are rarely one simple origin. A CDN, API gateway, service mesh, queue adapter, audit sink and application can each observe or transform different stages. Some may emit side effects before another component generates an error. The problem type does not standardize that execution graph.

A client that receives status 400 knows what response reached it. It does not thereby know that no authorization hold, audit record, idempotency reservation, webhook, queue message or business mutation occurred. Nor does the response itself prove which hop originated it when intermediaries can generate or modify responses.

RFC 9110 supplies the retry boundary. Idempotent methods can be retried automatically after a connection failure because repeating the intended request has the same intended effect. A client should not automatically retry a non-idempotent request unless it knows that the operation is actually idempotent or can determine that the first request was never applied. A proxy must not automatically retry non-idempotent requests. A client should not automatically retry a failed automatic retry.

The digest-problem draft includes examples involving PUT and POST. That is precisely why method and application semantics cannot be inferred from the type. A PUT may still carry conditional or external effects. A POST may be made safely repeatable through an idempotency key and a durable application record. The authority comes from those semantics and records, not from the word “mismatched”.

The minimum safe replay question is therefore not “did digest validation fail?” It is “can this caller prove, for this request identity and application operation, that repeating the request cannot create a second effect?” If the answer is unknown, the correct state is reconciliation, not automatic replay.

A small evidence envelope prevents a large fiction

Heng Lu's reality-layer discipline separates a symbol from execution and outcome. A digest is a symbolic claim about bytes in a named scope. A problem type is a server's statement about a validation attempt. A retry is a new action. Application commitment and customer outcome are later observations. Placing them in one Boolean called integrity_failed creates power without accountability: a low-layer diagnostic silently commands a high-layer business action.

A Minimum Initial Specification can remain compact. Preserve a stable request or operation identifier; method and target; attempt number; idempotency key or other replay authority; digest header and algorithm; a protected provided-value fingerprint; the hop that validated; actual HTTP status and problem type; response provenance; and the application receipt, rejection or unknown state. Do not fill an unknown application outcome from a validator error.

Running-Code Primacy turns the distinctions into tests. Send content through encoders that alter byte scope. Introduce an intermediary transform. Supply an unsupported algorithm, an impossible-length value and a valid mismatch. Omit optional extensions. Return several entries in different orders. Lose the first response after an application commits. Replay a POST with and without a durable idempotency key. Force the automatic retry to fail. The trace should expose uncertainty and stop conditions rather than converge on a green “retried successfully” label.

The draft makes HTTP integrity failures easier for software to understand. That is a reason to become more exact, not more aggressive. digest-mismatched-values can tell an operator where one comparison ceased to agree. Only application semantics and evidence can decide whether another request may begin.

Sources