HTTP 102 Processing is an interim status code defined in the WebDAV specification (RFC 2518) that tells the client the server has accepted the complete request but has not yet completed it. This prevents the client from timing out while the server performs a lengthy operation. Unlike 100 Continue which is about the request body, 102 Processing signals that the server is actively working on a fully received request that takes more than a few seconds to complete.
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/102
Example request:
curl -i "https://httpstatus.com/api/status/102"The server has received and is processing the request, but no response is available yet. Used in WebDAV to prevent client timeouts on long operations.
On this code, Inspector focuses on semantics, headers, and correctness warnings that commonly affect clients and caches.
102 Processing originated in WebDAV (RFC 2518) for operations like COPY or MOVE on large directory trees that could take minutes. The server periodically sends 102 responses as keep-alive signals. Crucially, this is NOT standard in HTTP/1.1 core — it's a WebDAV extension. The 102 response has no body and no required headers beyond the status line. Servers should send 102 at intervals (e.g., every 10-30 seconds) to prevent client/proxy timeouts. In HTTP/2, the PING frame serves a similar keep-alive purpose, making 102 less necessary. Note: RFC 4918 (the updated WebDAV spec) removed the 102 status code definition, making it effectively deprecated, though some implementations still use it.
const http = require('http');
const server = http.createServer(async (req, res) => {
if (req.url === '/long-task') {
// Send 102 Processing to prevent timeout
res.writeProcessing();
// Simulate long operation
const result = await performLongTask();
// Send another 102 if still processing
res.writeProcessing();
await finalizeTask(result);
// Final response
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ status: 'complete', result }));
}
});# Using raw ASGI for 102 support
async def app(scope, receive, send):
if scope['type'] == 'http':
# Send 102 interim response
await send({
'type': 'http.response.start',
'status': 102,
'headers': [],
})
# Perform long operation
result = await long_running_task()
# Send final response
await send({
'type': 'http.response.start',
'status': 200,
'headers': [[b'content-type', b'application/json']],
})
await send({
'type': 'http.response.body',
'body': json.dumps(result).encode(),
})// Spring Boot - raw servlet response for 102
@PostMapping("/long-task")
public void longTask(HttpServletRequest req,
HttpServletResponse res) throws Exception {
// Send 102 Processing interim response
res.setStatus(102);
res.flushBuffer();
// Perform long-running operation
Result result = heavyComputation();
// Send final 200 response
res.setStatus(200);
res.setContentType("application/json");
res.getWriter().write(objectMapper.writeValueAsString(result));
}func longTaskHandler(w http.ResponseWriter, r *http.Request) {
// Access the underlying connection for interim response
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming not supported", 500)
return
}
// Send 102 Processing (Go doesn't have native 1xx support,
// so use 202 Accepted pattern instead)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusAccepted)
flusher.Flush()
// For true 102, use a reverse proxy or custom conn handler
result := performLongTask()
json.NewEncoder(w).Encode(result)
}