Idempotent Payloads vs. ETag Conditional Requests for Safe Retries in Portainer API
0 reputation · 22 Oct 2020, 20:02 UTC
0 reputation · 22 Oct 2020, 20:02 UTC
The goal is to safely retry failed API calls through Portainer without causing duplicate writes when interacting with the Docker daemon via the /api/endpoints/{id}/docker proxy.
Portainer documents that create/update operations are idempotent when the request includes a stable identifier, and that conditional requests using If‑Match/ETag prevent duplicate writes for mutable resources. However, the Docker proxy endpoint does not return a stable ETag in version 2.19.x, making the conditional retry mechanism unreliable, and ad‑hoc commands lack natural idempotency.
35275 reputation · 23 Oct 2020, 00:46 UTC
For the /api/endpoints/{id}/docker proxy endpoint in Portainer 2.19.x, you should implement application-level deduplication using unique request identifiers. Because the Docker proxy does not return stable ETags, conditional requests (If-Match) cannot be used to ensure atomicity during retries.
The following table compares the viability of the three strategies mentioned in your request:
| Approach | Viability | Reasoning |
|---|---|---|
| Application-level Deduplication | High | Most reliable way to prevent duplicate writes when the server lacks native idempotency tokens. |
| External Locking/Serialization | Medium | Effective for single-client scenarios, but risks race conditions or deadlocks in distributed environments. |
| Client-side ETag Wrapper | Low | Generating ETags on the client does not solve the server-side state problem; the proxy will still execute the command regardless of a client-generated tag. |
PENDING.GET request to the Docker API (e.g., checking for a container name) before retrying.COMPLETED upon a successful 200/201 response.This recommendation assumes you are operating on Portainer 2.19.x where the Docker proxy acts as a transparent pass-through to the Docker daemon. To verify the lack of ETag support, execute the following check:
curl -I https://your-portainer/api/endpoints/{id}/docker/containers
If the ETag header is missing from the response, conditional retries are functionally impossible for that endpoint.
Missing Diagnostic: Are your API clients distributed across multiple nodes or centralized in a single service? If distributed, external locking must be implemented via a distributed lock manager (DLM) rather than local memory.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.