428 - Precondition Required
HTTP 428 Precondition Required means the origin requires conditional requests to prevent lost updates.
Last reviewed: February 26, 2026|Source-backed guidance under our editorial policy
Start Here
Use the closest compare guide, playbook, or adjacent error page to narrow the decision faster before you start changing production systems.
This page is part of the Error Reference library. Learn more about the project or report a correction.
What Does Precondition Required Mean?
The origin refuses unconditional mutations and requires preconditions so concurrent updates do not silently overwrite newer resource state.
Common Causes
- -Update route requires If-Match for concurrency control, and clients omitting header are rejected consistently.
- -Gateway policy enforces conditional DELETE headers for shared resources to prevent accidental destructive updates.
- -Sync worker retries stale writes without refreshing ETag, so server demands explicit precondition header.
How to Fix Precondition Required
- 1Fetch current resource validators (for example ETag) and send conditional headers on every mutation.
- 2Implement optimistic concurrency logic in clients to retry only after state refresh.
- 3Reject unconditional write paths in SDKs so missing preconditions are caught before network send.
Step-by-Step Diagnosis for Precondition Required
- 1Capture failing mutation request and confirm required conditional headers are absent or invalid.
- 2Inspect origin policy that mandates conditional writes and its documented validator requirements.
- 3Trace client write paths to identify callers bypassing ETag/version fetch before mutate.
- 4Retest with correct preconditions and verify lost-update protection remains intact.
Conditional Write Policy and Validator Coverage
- -Verify endpoint policy requiring conditionals (example: PUT without
If-Matchrejected by design with 428). - -Audit validator freshness logic (example: client reuses stale ETag from cache beyond allowed staleness window).
Client Concurrency Workflow Enforcement
- -Trace read-modify-write paths for missing precondition injection (example: mobile offline sync sends unconditional PATCH after reconnect).
- -Check SDK middleware behavior (example: bulk update helper omits conditional headers for batched operations).
Implementation Examples
curl -i -X PUT https://api.example.com/v1/resource/42 -H "Content-Type: application/json" -d "{"status":"approved"}"
# Response:
# HTTP/1.1 428 Precondition Required
# {"error":"Precondition Required","code":"428"}const response = await fetch('https://api.example.com/v1/resource/42', {
method: 'PUT',
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
body: JSON.stringify({ status: 'approved' })
});
if (response.status === 428) {
console.error('Handle 428 Precondition Required');
}import requests
response = requests.put(
'https://api.example.com/v1/resource/42',
headers={'Accept': 'application/json', 'Content-Type': 'application/json'},
json={'status': 'approved'}
)
if response.status_code == 428:
print('Handle 428 Precondition Required')Seen in Production
Client updates shared record without reading latest validator
Frequency: common
Example: Mobile app sends unconditional PUT on sync and API enforces precondition policy with 428.
Fix: Fetch latest ETag before mutate and include If-Match in every update call.
Bulk updater bypasses SDK concurrency middleware
Frequency: rare
Example: Internal batch job uses raw HTTP client, omits conditional headers, and receives 428 for all mutations.
Fix: Route bulk job through shared SDK/write wrapper that automatically attaches validators.
Debugging Tools
- -ETag/validator inspection via HEAD/GET traces
- -Write-path middleware logs for conditional header injection
- -Concurrency simulation tests
- -Audit logs for blocked unconditional mutations
How to Verify the Fix
- -Repeat mutations with valid preconditions and confirm 428 is cleared for compliant requests.
- -Run concurrent update tests to ensure unconditional requests are still blocked intentionally.
- -Validate conflict-resolution UX and retry flow for stale validator cases.
How to Prevent Recurrence
- -Adopt optimistic concurrency tokens and idempotency guards for mutating operations.
- -Serialize high-contention writes and enforce deterministic dependency ordering.
- -Monitor precondition and lock-related failure signals with actionable alerts.
Pro Tip
- -make conditional headers mandatory in generated SDK mutation methods so developers cannot accidentally send unconditional writes.
Official References
Provider Context
This guidance is specific to HTTP services. Always validate implementation details against official provider documentation before deploying to production.