-
Type:
Task
-
Resolution: Won't Do
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
-
Query Execution
-
QE 2026-06-22
-
None
-
None
-
None
-
None
-
None
-
None
-
None
Problem
Code 512 WriteConflictRetryLimitExceeded (SERVER-126462) is tagged with both SystemOverloadedError and RetriableError categories in src/mongo/base/error_codes.yml. The [Client Backpressure spec|https://github.com/mongodb/specifications/blob/master/source/client-backpressure/client-backpressure.md] defines a "Retryable Overload Error" as a response carrying both SystemOverloadedError and RetryableError labels, and mandates that spec-compliant drivers apply jittered exponential backoff and retry.
Today ErrorLabelBuilder in src/mongo/db/error_labels.cpp (lines 215-238) attaches RetryableError only when isOperationIdempotent() is true, which currently fires only for code 462 IngressRequestRateLimitExceeded per the TODO at SERVER-108898. Code 512 gets only SystemOverloadedError, so the spec's dual-label trigger is never satisfied.
Once a spec-compliant PyMongo ships (DRIVERS-3427, currently on master only), applications hitting code 512 still will not get the spec-mandated backoff retry because the server is not emitting the second label.
Scope
Attach ErrorLabel::kRetryableError to responses for any error in the [SystemOverloadedError, RetriableError] category pair. Decouple from isOperationIdempotent() so the NoWritesPerformed label is not also attached for codes (like 512) where retries may have applied partial side effects.
Proposed implementation
In ErrorLabelBuilder::build() (around line 232 of error_labels.cpp), add a new branch:
} else if \(isRetryableOverloadError\(\)\) { labels << ErrorLabel::kRetryableError; } else if \(isOperationIdempotent\(\)\) { labels << ErrorLabel::kRetryableError; labels << ErrorLabel::kNoWritesPerformed; }
with the helper:
bool ErrorLabelBuilder::isRetryableOverloadError\(\) const { return \_code && mongo::isSystemOverloadedError\(\_code.value\(\)\) && ErrorCodes::isRetriableError\(\_code.value\(\)\); }
This picks up code 512 automatically and any future code added to both categories.
Why not just extend isOperationIdempotent()?
That method attaches both RetryableError and NoWritesPerformed. Drivers treat NoWritesPerformed as a hard guarantee that no writes were applied. For code 512, the executor only sheds after N consecutive WriteConflictExceptions, and earlier retries may have committed partial work before later retries conflicted. So NoWritesPerformed would be incorrect for 512.
Client-side gating is preserved
Per the Client Backpressure spec step 2.4, drivers gate retry on the client's retryWrites/retryReads setting even when both labels are present. A user with retryWrites=false sees the labels but PyMongo will not auto-retry. Correct behavior - labels describe the error, the policy gate is a separate layer.
Acceptance criteria
- Code 512 WriteConflictRetryLimitExceeded carries both SystemOverloadedError and RetryableError labels in the response errorLabels array.
- Code 512 does not carry NoWritesPerformed.
- Code 462 IngressRequestRateLimitExceeded keeps its current label set (SystemOverloadedError, RetryableError, NoWritesPerformed).
- C++ unit test in src/mongo/db/error_labels_test.cpp covering the two label sets above.
- jstests/noPassthrough/query/write_conflict_retry_limit.js asserts the RetryableError label on shed responses.
Related
- SPM-4627 (parent epic: Reduce the impact of write conflict retry storms)
- SERVER-126462 (introduced code 512 with both categories; consumer of this label)
- SERVER-108898 (existing TODO to extend isOperationIdempotent())
- DRIVERS-3427 (PyMongo Client Backpressure spec implementation; the future consumer)
- PERF-8826 (DSI workload; uses a codeName-based classifier today as a workaround for this gap)