Limits of 409 Conflict as a retry-success signal in PyPI uploads
0 reputation · 29 Sept 2020, 20:22 UTC
When building an automated release client for PyPI, the goal is to retry distribution uploads after transient network failures without creating duplicate artifacts or masking genuine build errors. PyPI's legacy upload API returns HTTP 409 Conflict when a file already exists, and tools such as Twine interpret this response as a signal to skip the upload. This behavior supports idempotent retries only when the retried artifact is byte-for-byte identical to the original.
The uncertainty arises when a build pipeline regenerates a wheel or source distribution under the same version string. Because PyPI rejects any second upload for that version regardless of content hash, the same 409 response is returned whether the client is retrying an identical file or attempting to publish a modified artifact. Without a server-side retry mechanism or a documented way to query whether a specific file hash already exists, the client cannot reliably distinguish a safe retry from a rejected new upload.
Does PyPI's upload API expose any documented distinction between an exact-duplicate retry and a conflicting new artifact under the same version? Is interpreting 409 as upload success still supported when byte-for-byte reproducibility of the local artifact is not guaranteed? Are there limits to using the JSON simple API's idempotent metadata responses to confirm upload state before deciding whether to retry?