Dishita - I think the documentation and client-side pieces are the way to
go.  In that case, the documentation at Fineract is only one side of the
contract. That can be better documented and logged.

I think logging when a key is missing is a useful feature, provided it
doesn't create additional overhead and can be "turned off" when other
enforcement mechanisms are in place.




On Wed, Apr 22, 2026 at 12:37 PM Dishita Suyal <[email protected]>
wrote:

> Hi,
>
> I’ve created a JIRA issue to improve observability by logging when the
> Idempotency-Key header is missing:
>
> FINERACT-2591
>
> Happy to work on this if it aligns with the project direction.
>
> Thanks,
> Dishita
>
> On Thu, Apr 23, 2026 at 12:45 AM Dishita Suyal <[email protected]>
> wrote:
>
>> Hi everyone,
>>
>> Thank you for raising and discussing this topic — it was very insightful.
>>
>> From my understanding, enforcing deterministic idempotency on the server
>> side when the client does not provide a key could introduce risks,
>> especially in financial workflows where identical payloads may still
>> represent distinct business intents (e.g., multiple valid repayments within
>> a short time window).
>>
>> It seems more aligned with the current architecture that idempotency
>> remains a client-driven contract, with the server enforcing it only when an
>> explicit key is provided.
>>
>> Would it make sense to instead focus on improving client-side guidance or
>> safeguards (for example, better documentation or warnings when the key is
>> missing), rather than introducing server-side fallback behavior?
>>
>> I’d appreciate your thoughts on this.
>>
>> Regards,
>> Dishita
>>
>> On Fri, Apr 17, 2026 at 5:30 PM Mohammed Saifulhuq <
>> [email protected]> wrote:
>>
>>> Hi Lukman, Adam,
>>>
>>> I completely agree with Adam's assessment. Enforcing server-side
>>> deterministic key generation based solely on payload introduces severe
>>> risks to core banking operations.
>>>
>>> In microfinance, it is entirely valid for a client to submit two
>>> identical business intents in a short window (e.g., making two separate $50
>>> loan repayments on the same day). If the server automatically generates a
>>> fallback key based on that payload, the Idempotency Filter will falsely
>>> flag the second legitimate payment as a duplicate and block it with a 409
>>> Conflict. This corrupts the ledger.
>>>
>>> Idempotency must remain a strict client-server contract. The client owns
>>> the intent; the server enforces the lock.
>>>
>>> In the system-wide idempotency architecture mapped out for FINERACT-2169
>>> / FINERACT-2485, this is handled explicitly to ensure zero regression:
>>>
>>> 1. The OncePerRequestFilter strictly targets the Idempotency-Key HTTP
>>> header.
>>>
>>> 2. If the header is missing, the filter bypasses the PostgreSQL lookup
>>> entirely ($O(1)$ exit) and allows the request to pass to the legacy
>>> command processing pipeline.
>>>
>>> 3. Payload canonicalization and hashing are used strictly for integrity
>>> verification (ensuring a client doesn't maliciously reuse the same key for
>>> a different payload), never for fallback key generation.
>>>
>>> The global configuration flag allows legacy clients to continue
>>> operating without keys, while modern clients can opt-in to the safe
>>> execution path.
>>>
>>> Regards,
>>>
>>> Mohammed Saifulhuq
>>>
>>> On Fri, Apr 17, 2026 at 3:53 PM Ádám Sághy <[email protected]> wrote:
>>>
>>>> Hi
>>>>
>>>> Thank you for raising this topic!
>>>>
>>>> In my understanding, if no idempotency key is provided, we should not
>>>> enforce idempotent behavior.
>>>>
>>>> While I understand where the fallback logic is coming from, I am
>>>> hesitant to go on that path:
>>>>
>>>>
>>>>    - “Same payload” is not always the same business intent.
>>>>    - shifts idempotency responsibility from the client contract to
>>>>    server inference
>>>>    - it can mean blocking a valid transaction
>>>>
>>>>
>>>> For these reasons, I am not sure we should enforce this as default
>>>> fallback. Maybe it is as an optional thing would be better?
>>>>
>>>> Regards,
>>>> Adam
>>>>
>>>>
>>>> On Apr 9, 2026, at 2:07 PM, elnafateh <[email protected]> wrote:
>>>>
>>>> Hi everyone,
>>>>
>>>> I would like to raise a discussion regarding idempotency handling in
>>>> Fineract, specifically when a client does not provide an idempotency key.
>>>> Problem
>>>>
>>>> Currently, if a client omits the idempotency key, the system may
>>>> generate a random UUID per request. In retry scenarios, this can lead to
>>>> duplicate processing of the same logical operation.
>>>>
>>>> A typical scenario:
>>>>
>>>>    1.
>>>>
>>>>    Client sends a request (e.g., funds transfer)
>>>>    2.
>>>>
>>>>    Server processes and commits successfully
>>>>    3.
>>>>
>>>>    Client does not receive the response (e.g., network timeout)
>>>>    4.
>>>>
>>>>    Client retries the same request without an idempotency key
>>>>    5.
>>>>
>>>>    A new UUID is generated → request is treated as a new operation
>>>>
>>>> This can result in unintended duplicate transactions (e.g., double
>>>> spending).
>>>> Proposal
>>>>
>>>> Instead of generating a random UUID, generate a deterministic
>>>> idempotency key based on:
>>>>
>>>>    -
>>>>
>>>>    Request payload
>>>>    -
>>>>
>>>>    Relevant context (e.g., clientId, entityName,ActionName etc)
>>>>    -
>>>>
>>>>    Optional bounded time window
>>>>
>>>> This ensures that repeated identical requests map to the same
>>>> idempotency key, even when the client does not explicitly provide one.
>>>> Open Questions
>>>>
>>>>    -
>>>>
>>>>    Should the system enforce idempotency even when the client does not
>>>>    provide a key?
>>>>    -
>>>>
>>>>    Is deterministic key generation an acceptable fallback strategy?
>>>>    -
>>>>
>>>>    Are there concerns around edge cases (e.g., payload variations,
>>>>    time window constraints)?
>>>>
>>>> I would really appreciate feedback on whether this problem is valid in
>>>> the context of Fineract and if this approach aligns with the project’s
>>>> design principles.
>>>>
>>>> Thanks,
>>>> Lukman Fateh
>>>>
>>>>
>>>>

Reply via email to