HTTP 428 Precondition Required (RFC 6585) indicates the server requires the request to include conditional headers (If-Match, If-Unmodified-Since). Unlike 412 Precondition Failed (where a condition was present but failed), 428 means no condition was provided at all. This enforces optimistic concurrency — the server demands the client prove it has the latest version before making changes, preventing accidental overwrites.
Response includes the status code, standard headers (including Content-Type), and a small diagnostic JSON body describing the request and returned status.
Simulator URL (copy in the app after load — not a normal link):
https://httpstatus.com/api/status/428
Example request:
curl -i "https://httpstatus.com/api/status/428"The origin server requires the request to be conditional.
On this code, Inspector focuses on semantics, headers, and correctness warnings that commonly affect clients and caches.
HTTP 428 Precondition Required has specific technical implications for API design, caching, and client behavior. Understanding the precise semantics helps distinguish it from similar status codes and implement correct error handling. The response should include a descriptive body following a consistent error schema (like RFC 7807 Problem Details) so clients can programmatically handle the error.
// Handle 428 Precondition Required in Express
app.use((err, req, res, next) => {
if (err.status === 428) {
return res.status(428).json({
type: 'https://api.example.com/errors/precondition-required',
title: 'Precondition Required',
status: 428,
detail: err.message
});
}
next(err);
});from fastapi import HTTPException
# Raise 428 Precondition Required
raise HTTPException(
status_code=428,
detail={
'type': 'precondition_required',
'message': 'Descriptive error for 428 Precondition Required'
}
)// Spring Boot 428 Precondition Required handling
@ExceptionHandler(CustomPreconditionRequiredException.class)
public ResponseEntity<ErrorResponse> handlePreconditionRequired(
CustomPreconditionRequiredException ex) {
return ResponseEntity.status(428)
.body(new ErrorResponse("Precondition Required", ex.getMessage()));
}// Return 428 Precondition Required
func errorHandler(w http.ResponseWriter, message string) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(428)
json.NewEncoder(w).Encode(map[string]any{
"status": 428,
"error": "Precondition Required",
"message": message,
})
}