Skip to content

205 Reset Content

What is HTTP 205 Reset Content?

205 Reset Content
When you fill out a form on a website and submit it, sometimes the website says ...
HTTP 205 Reset Content status code illustration

Explain Like I’m 3

You did something and it worked! Now it’s time to start fresh and do it again! Like when you finish coloring a picture and someone gives you a clean new page to color!

Example: You fill out a form with your name and age, and press send. It works! Then your paper magically becomes blank again so you can fill it out for someone else!

Explain Like I’m 5

When you fill out a form on a website and submit it, sometimes the website says ‘205 Reset Content’ which means ‘Thanks! I got your information. Now I’m going to clear the form so you can fill it out again if you want!’ It’s like an etch-a-sketch - you drew your picture, someone saved it, and then they shake it clean so you can draw a new one. This is helpful for forms where people might want to enter multiple things, like adding items to a list or submitting survey responses over and over.

Example: You’re on a website where you submit names for a guest list. You type ‘Alice’ and click submit. The website says ‘205 Reset Content!’ and clears the form. Now you can type ‘Bob’ and submit again, then ‘Charlie’, and keep going!

Jr. Developer

HTTP 205 Reset Content indicates the request succeeded and the client should reset the document view - essentially clearing the form or input fields that were just submitted. This is intended for data entry scenarios where users submit content repeatedly. However, browsers don’t automatically reset forms on 205 - you must handle it in JavaScript. When you receive 205 in a fetch() or AJAX request, detect the status code and programmatically clear your form fields, reset state, or refresh the view. Like 204, the 205 response MUST NOT include a message body - set Content-Length to 0 or omit it entirely. The use case is narrow: repetitive data entry like adding multiple items to a list, survey responses, batch data entry, or logging multiple entries. For most CRUD operations, 200/201/204 are more appropriate. 205 is quite rare in modern APIs because client-side frameworks usually handle form resets automatically, and returning the created resource (201) or just success (204) is simpler.

Example: You’re building an expense tracker where users add multiple expenses in one session. After POST /expenses with {amount: 50, category: ‘Food’}, instead of returning 201 with the created expense, you return 205. Your frontend detects this and clears the form, letting users immediately add the next expense without manually clearing fields.

Code Example

// Server-side: Express returning 205
app.post('/api/expenses', async (req, res) => {
const expense = await db.createExpense(req.body);
// Return 205 to signal 'reset the form'
res.status(205)
.set('Content-Length', '0')
.end();
});
// Client-side: Handle 205 and reset form
const form = document.querySelector('#expense-form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const response = await fetch('/api/expenses', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
amount: form.amount.value,
category: form.category.value
})
});
if (response.status === 205) {
// Server told us to reset the form
form.reset();
showNotification('Expense added! Add another?');
} else if (response.status === 201) {
// Normal creation response
const expense = await response.json();
showNotification('Expense added!');
}
});

Crash Course

205 Reset Content, defined in RFC 9110 Section 15.3.6, indicates the server successfully processed the request and the client should reset the document view that caused the request to be sent. The original intent was for data entry use cases where users submit forms repeatedly - after successful submission, the form should be cleared for the next entry. Per the RFC: ‘This response is intended to support a use case where the user receives content that supports data entry (a form, notepad, canvas, etc.), causes user-entered data to be submitted in a request, and the content needs to be reset for the next entry.’ Critical implementation detail: browsers do NOT automatically reset forms when receiving 205 - this must be handled in JavaScript by detecting the status code and programmatically clearing inputs. Like 204, the 205 response MUST NOT contain a message body - the server must set Content-Length to 0 or use chunked encoding with an empty chunk. The status is extremely rare in modern web development for several reasons: SPAs handle form resets client-side anyway, returning the created resource (201 with body) is more informative, client-side frameworks make automatic reset easy without server signals, and many developers simply aren’t aware 205 exists. Valid use cases: batch data entry forms (expenses, inventory items, survey responses), logging systems where users enter multiple entries, data import wizards with row-by-row validation, kiosk interfaces with repetitive transactions. For most REST APIs, 201 Created or 204 No Content are better choices. 205 is only useful when you specifically want to signal ‘clear the form for the next entry’ and your client is prepared to handle it.

Example: A warehouse inventory system has a barcode scanning interface. Workers scan items one by one to log them into inventory. Each scan sends POST /inventory/items with barcode and quantity. The server validates the item, adds it to inventory, and returns 205 Reset Content. The scanning interface detects 205, clears the barcode input field, plays a success beep, and focuses the input for the next scan. Without 205 signaling, the worker would need to manually clear the field between scans. The 205 status creates a seamless rapid-entry workflow.

Code Example

// Server: Batch data entry endpoint
const express = require('express');
const app = express();
app.post('/api/inventory/scan', async (req, res) => {
const { barcode, quantity, location } = req.body;
// Validate
if (!barcode || !quantity) {
return res.status(400).json({ error: 'Missing required fields' });
}
// Check if item exists
const item = await db.getItemByBarcode(barcode);
if (!item) {
return res.status(404).json({ error: 'Unknown barcode' });
}
// Add to inventory
await db.addInventory({
itemId: item.id,
quantity,
location,
scannedBy: req.user.id,
scannedAt: new Date()
});
// Return 205 to signal 'reset the form for next scan'
res.status(205)
.set('Content-Length', '0')
.end();
});
// Client: Inventory scanning interface
class InventoryScanner {
constructor() {
this.form = document.querySelector('#scan-form');
this.barcodeInput = document.querySelector('#barcode');
this.quantityInput = document.querySelector('#quantity');
this.statusDiv = document.querySelector('#status');
this.form.addEventListener('submit', (e) => this.handleScan(e));
}
async handleScan(e) {
e.preventDefault();
const data = {
barcode: this.barcodeInput.value,
quantity: parseInt(this.quantityInput.value),
location: 'WAREHOUSE-A'
};
try {
const response = await fetch('/api/inventory/scan', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (response.status === 205) {
// Server told us to reset for next entry
this.form.reset();
this.showSuccess('Item scanned! Ready for next item.');
this.barcodeInput.focus(); // Focus for next scan
this.playBeep(); // Audio feedback
} else if (response.ok) {
// Unexpected success status (maybe API changed to 201)
this.showSuccess('Item scanned!');
this.form.reset();
this.barcodeInput.focus();
} else {
const error = await response.json();
this.showError(error.error || 'Scan failed');
this.barcodeInput.select(); // Select for re-entry
}
} catch (error) {
this.showError('Network error: ' + error.message);
}
}
showSuccess(message) {
this.statusDiv.textContent = message;
this.statusDiv.className = 'status success';
}
showError(message...

Deep Dive

The 205 Reset Content status code, specified in RFC 9110 Section 15.3.6, indicates that the server has fulfilled the request and desires that the user agent reset the ‘document view,’ which caused the request to be sent, to its original state as received from the origin server. The RFC elaborates: ‘This response is intended to support a use case where the user receives content that supports data entry (a form, notepad, canvas, etc.), causes user-entered data to be submitted in a request, and the content needs to be reset for the next entry so that the user can easily initiate another input action.’ The status exists to facilitate repetitive data entry workflows where clearing the input interface after each successful submission streamlines the process.

Technical Details

The phrase ‘document view’ in the RFC specification is intentionally abstract to cover various user agents and interaction models. For HTML forms in browsers, it implies resetting form fields to their original values. For rich web applications, it might mean clearing canvas elements, resetting text editors, or returning to an initial application state. Critically, RFC 9110 states that resetting content is NOT automatically handled by browsers - it’s a signal that application code must act upon. This design decision reflects that automatic form reset could be dangerous (users might lose carefully entered data due to accidental submission), so the server suggests reset but the client decides.\n\nLike 204 No Content, the 205 response MUST NOT include a message body. Per RFC 9110: ‘The server MUST NOT generate content in a 205 response.’ The response is terminated by the first empty line after header fields. If Content-Length is included, it MUST be 0. For chunked transfer encoding, only the terminating zero-length chunk is sent. Violating this by including a body causes undefined behavior in HTTP clients - some might read and discard the body, others might leave it in the socket buffer causing protocol errors on persistent connections.\n\nCaching semantics: 205 responses are not typically cacheable, as they represent an action (successful submission) rather than a resource representation. RFC 9111 doesn’t explicitly address 205 caching, but the absence of content makes caching meaningless. Cache directives like Cache-Control: no-store are superfluous but harmless.\n\nComparison with alternatives: 201 Created returns the created resource representation, providing confirmation and often a resource ID, but doesn’t signal form reset. 204 No Content confirms success without content but doesn’t specifically suggest reset. 200 OK with instructions in the body (e.g., {“action”: “reset”}) provides explicit guidance but increases bandwidth and coupling. 205 is semantically precise for ‘success, now reset’ but requires client-side logic to detect and handle it.\n\nHistorical context: 205 was defined in HTTP/1.1 (RFC 2616, 1999) to support traditional server-rendered web applications where form submissions were synchronous navigation events. In that era, a 205 response could theoretically trigger browser behavior to reset forms. However, browsers never implemented automatic reset due to data loss concerns. The rise of AJAX (XMLHttpRequest), fetch API, and single-page applications made 205 even less relevant - SPAs control all UI state and can reset forms trivially without server hints.\n\nModern usage patterns: 205 appears primarily in specialized applications with domain-specific workflows: point-of-sale terminals, kiosk interfaces, barcode scanning systems, batch data entry UIs, laboratory information systems (entering test results), call center scripts (logging call data), time tracking systems (clocking in/out). In these contexts, rapid sequential entry…

Code Example

// Production-grade 205 implementation for batch entry\nconst express = require('express');\nconst { body, validationResult } = require('express-validator');\nconst rateLimit = require('express-rate-limit');\nconst app = express();\n\n// Rate limiting for rapid entry endpoints\nconst entryLimiter = rateLimit({\n windowMs: 1 * 60 * 1000, // 1 minute\n max: 100, // 100 entries per minute\n message: 'Too many entries, please slow down',\n standardHeaders: true,\n legacyHeaders: false\n});\n\n// Batch survey response entry\napp.post('/api/surveys/:id/responses',\n entryLimiter,\n body('answers').isArray(),\n body('answers.*.questionId').isInt(),\n body('answers.*.answer').notEmpty(),\n async (req, res) => {\n const errors = validationResult(req);\n if (!errors.isEmpty()) {\n return res.status(400).json({ errors: errors.array() });\n }\n \n const { answers } = req.body;\n const surveyId = req.params.id;\n \n try {\n // Validate survey exists\n const survey = await db.getSurvey(surveyId);\n if (!survey) {\n return res.status(404).json({ error: 'Survey not found' });\n }\n \n // Validate all question IDs\n const questionIds = answers.map(a => a.questionId);\n const validQuestions = await db.getQuestions(surveyId);\n const validIds = validQuestions.map(q => q.id);\n \n const invalidIds = questionIds.filter(id => !validIds.includes(id));\n if (invalidIds.length > 0) {\n return res.status(400).json({\n error: 'Invalid question IDs',\n invalidIds\n });\n }\n \n // Create response record\n const responseId = await db.createSurveyResponse({\n surveyId,\n submittedBy: req.user.id,\n submittedAt: new Date(),\n answers\n });\n \n // Audit log\n await db.logAudit({\n action: 'survey_response_submitted',\n userId: req.user.id,\n surveyId,\n responseId,\n timestamp: new Date()\n });\n \n // Return 205 to signal 'ready for next response'\n res.status(205)\n .set({\n 'Content-Length': '0',\n 'X-Response-Id': responseId,\n 'X-Entry-Count': await db.getUserEntryCount(req.user.id, surveyId)\n })\n .end();\n \n } catch (error) {\n console.error('Survey submission error:', error);\n res.status(500).json({ error: 'Internal server error' });\n }\n }\n);\n\n// Time tracking punch-in endpoint\napp.post('/api/timeclock/punch',\n entryLimiter,\n body('action').isIn(['in', 'out', 'break-start', 'break-end']),\n body('location').optional().isString(),\n async (req, res) => {\n const { action, location } = req.body;\n const userId = req.user.id;\n \n // Get last punch for validation\n const lastPunch = await db.getLastPunch(userId);\n \n // Validate punch sequence\n if (action === 'in' && lastPunch?.action === 'in') {\n r...

Frequently Asked Questions

Do browsers automatically reset forms when receiving 205?

No! Browsers do NOT automatically reset forms on 205. You must detect the 205 status in JavaScript and programmatically call form.reset(). The 205 status is just a signal from the server suggesting reset - your client code must implement the actual reset behavior.

When should I use 205 instead of 201 or 204?

Use 205 only for repetitive data entry workflows where users will immediately submit another entry (batch data entry, scanning systems, survey collection). Use 201 when you want to return the created resource. Use 204 for single deletions/updates with no content to return. 205 is quite rare and most APIs don't need it.

Can I include response body with 205?

No! Per RFC 9110, 205 responses MUST NOT contain a message body, just like 204. The server must set Content-Length to 0 or omit it. Use res.status(205).end() in Express, never .json() or .send(). If you need to return data, use 200 or 201 instead.

What's the difference between 204 No Content and 205 Reset Content?

Both prohibit message bodies, but semantically 204 means 'success, nothing to return' while 205 means 'success, reset your input form for the next entry.' 204 is for general no-content scenarios (DELETE, PUT), while 205 is specifically for repetitive data entry. 205 implies the workflow continues; 204 implies the operation is complete.

Is 205 supported by modern frameworks?

All HTTP frameworks support setting status 205 (it's just a number), but client-side handling requires custom JavaScript. Libraries like fetch(), axios, and jQuery don't automatically reset forms on 205 - you must check response.status === 205 and implement reset logic yourself. Most developers aren't familiar with 205, so document it clearly if you use it.

Common Causes

  • Batch data entry form where users submit multiple entries sequentially
  • Barcode scanning system logging items one by one
  • Survey response collection with repetitive submissions
  • Time clock punch-in/out kiosk interface
  • Laboratory results entry system (multiple test results)
  • Inventory management rapid entry interface
  • Call center logging system (multiple call records)
  • Point-of-sale transaction entry (rarely used in POS)

Implementation Guidance

  • Server-side: Use res.status(205).end() - never include body with 205
  • Server-side: Set Content-Length to 0 or omit it entirely
  • Server-side: Only use 205 for truly repetitive data entry workflows
  • Client-side: Check if (response.status === 205) in fetch/AJAX handlers
  • Client-side: Call form.reset() when receiving 205
  • Client-side: Focus first input field after reset for seamless continuation
  • Client-side: Provide feedback (audio beep, visual confirmation) on successful reset
  • Document the 205 behavior clearly for client developers
  • Consider if 201 (with resource) or 204 (no content) would be simpler
  • For public APIs, avoid 205 - use conventional status codes
  • Add rate limiting to prevent abuse of rapid entry endpoints

Comments