Skip to content

fix(aws): AlreadyExists after a committed buy reports failure when the token is empty; exchange accept has no retry guard #299

Closed

Description

@cristim

Summary

Two related gaps found while reviewing go#297 (MON-02), neither fixed there:

  1. RDS, ElastiCache, MemoryDB and OpenSearch use a deterministic per-call reservation ID, so a retry after a committed buy gets AlreadyExists. recoverAlreadyExists refuses to treat that as success when the idempotency token is empty, so such a retry reports a failure although the commitment exists.
  2. AcceptReservedInstancesExchangeQuote in pkg/exchange uses the default SDK retryer and carries no token (observation by the PR reviewer; relates to MON-17).

Current behaviour

(1) A retry that hits AlreadyExists with an empty token returns an error even though the earlier attempt succeeded. (2) The exchange accept call can be retried by the SDK after a lost response with nothing to collapse the second accept onto the first.

Steps to verify the gap

(1) Read recoverAlreadyExists in the AWS service clients and its empty-token branch. (2) Read the accept call in exchange.executeWithAPI and the client's retry configuration.

Expected behaviour

(1) An AlreadyExists on a deterministic reservation ID resolves to the existing commitment regardless of the token. (2) The exchange accept is sent once, or is made idempotent, with a lost response reported as outcome unknown.

Proposed fix

(1) Match the existing reservation by its deterministic ID. (2) Apply the per-operation RetryMaxAttempts = 1 pattern from go#297 and classify the error with purchasecfg.ClassifyPurchaseError-style wrapping.

References

Parent: go#296, go#297. Severity: medium for (1), high for (2) if exchanges can be re-driven.

Activity

  1. self-assigned this
    on Oct 16, 2026
  2. cristim commented on Oct 16, 2026

    @cristim
    MemberAuthor

    Claiming: working on this.

  3. cristim commented on Oct 16, 2026

    @cristim
    MemberAuthor

    Reopening: #442 (part 2, the exchange accept) merged as 25bffb5 and its Closes closed this issue early. Part 1, the empty-token reservation purchases in RDS/ElastiCache/MemoryDB/OpenSearch, is still open in #429. This can close once #429 merges.

  4. cristim commented on Oct 16, 2026

    @cristim
    MemberAuthor

    Both parts are on main now. Part 1, the empty-token reservation purchases: #429, merged as 53dfba9. Part 2, the exchange accept: #442 (25bffb5). Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions