Skip to content

Standardize response-side semantics for idempotency errors #51

@tkawa

Description

@tkawa

I think several open and previously closed issues may be pointing to the same remaining gap in the draft: Idempotency-Key is standardized as a request field, but the response-side semantics still seem only partly standardized for interoperable clients.

At least, it looks related to:

And also some earlier closed discussions, such as:

I may be misunderstanding the intended scope, but the pattern I see is something like this:

  • the request-side signal is standardized (Idempotency-Key)
  • some failure handling is standardized, but only at a fairly coarse level via status codes
  • a lot of the remaining meaning is still carried by implementation-specific problem details and/or out-of-band documentation

Why this still feels under-specified

Moving toward Problem Details was a good step in my opinion (and better than relying only on Link rel="describedby" plus human-readable documentation). But if the type values are still implementation-specific documentation URIs, then the response is machine-readable syntactically, while the semantics are still not really standardized for interoperable clients.

For example, the current draft seems to rely mainly on 400, 409, and 422 for idempotency-related errors. Those status codes are definitely useful, but they still seem too coarse-grained to fully communicate idempotency-specific behavior to generic clients, SDKs, middleware, or other reusable tooling.

A client may still want to know, in a standardized way:

  • whether a 409 specifically means "the original request is still outstanding"
  • whether a 422 specifically means "the same idempotency key was reused with a different payload/fingerprint"
  • whether a missing key is required for this operation
  • whether the key is malformed
  • whether the server no longer retains the previous idempotency state

Right now, those semantics still seem mostly implementation-specific.

Possible direction: standard Problem Details types

Would it make sense for the draft to define a small set of standard Problem Details types for common idempotency cases?

For example, the draft could define specification-level problem types for cases like:

  • missing idempotency key
  • malformed idempotency key
  • reused key with a different request payload / fingerprint mismatch
  • original request still outstanding
  • key expired / no longer retained

Just as an illustration, that could mean stable identifiers along the lines of:

  • urn:ietf:params:problem-type:idempotency-key-missing
  • urn:ietf:params:problem-type:idempotency-key-malformed
  • urn:ietf:params:problem-type:idempotency-fingerprint-mismatch
  • urn:ietf:params:problem-type:idempotency-request-outstanding
  • urn:ietf:params:problem-type:idempotency-key-expired

I am not trying to suggest any specific URI scheme or registration policy here; those identifiers are only examples. The main point is that the semantics themselves would be standardized, instead of being left to vendor-specific documentation URLs.

That would still let the draft use ordinary HTTP status codes, while giving clients more precise, specification-defined semantics.

The success path may also still be ambiguous

Separately, some of the more recent discussions also seem to show that the success path is still a bit ambiguous in practice.

For example, it may still be useful for a client to know:

  • whether a successful response reflects a newly executed operation or a replay of a previously completed result
  • whether the supplied Idempotency-Key was actually recognized and enforced
  • whether any retention/validity window applies after success

I mention this mainly because issues like #46 and #48 seem to show that the ambiguity is not limited to error responses.

Question for the WG

Would the WG consider standardizing a small amount of response-side semantic detail, at least for common idempotency error cases, so that idempotency is not only standardized on the request path but also more interoperable on the response path?

Even if success-side signaling is left for later or handled separately, standard Problem Details types for common error cases already seem like they could improve interoperability quite a bit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions