Referensi lengkap HTTP status codes dari 1xx sampai 5xx yang wajib kamu tau buat web development!
Status codes yang menunjukkan bahwa request telah diterima dan diproses, tetapi belum selesai.
Respon informasional yang bilang request masih diproses
Server telah menerima request headers dan client dapat melanjutkan mengirim request body.
HTTP/1.1 100 ContinueServer udah terima request headers, client boleh lanjutin kirim body
Kapan dipake:
Server setuju untuk beralih protokol, biasanya dari HTTP ke WebSocket atau protokol lain.
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: UpgradeServer setuju switch protokol (contoh: HTTP ke WebSocket)
Server masih memproses request tetapi belum selesai, digunakan untuk mencegah timeout.
HTTP/1.1 102 ProcessingServer udah terima request, tapi masih proses (gak timeout)
Server memberikan hint kepada client untuk memuat resource sebelum response final dikirim.
HTTP/1.1 103 Early Hints
Link: </style.css>; rel=preload; as=style
Link: </script.js>; rel=preload; as=scriptKasih tau client buat preload resource sambil nunggu response final
Use case:
Status codes yang menunjukkan bahwa request berhasil diproses oleh server.
Request berhasil diproses!
Request berhasil dan response body berisi data yang diminta.
HTTP/1.1 200 OK
Content-Type: application/json
{
"message": "Success banget!"
}Request berhasil, ini datanya
Dipake untuk:
HTTP/1.1 201 Created
Location: /api/users/123
Content-Type: application/json
{
"id": 123,
"name": "Budi"
}Resource baru berhasil dibuat
Best practice:
Location headerHTTP/1.1 202 Accepted
Content-Type: application/json
{
"job_id": "abc123",
"status": "processing"
}Request diterima tapi belum selesai diproses (async)
Kapan dipake:
HTTP/1.1 203 Non-Authoritative InformationRequest sukses, tapi data dari proxy/cache (bukan origin server)
HTTP/1.1 204 No ContentRequest sukses, tapi gak ada data yang dikembalikan
Use case:
HTTP/1.1 205 Reset ContentRequest sukses, client harus reset document view (clear form)
HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/10240
Content-Length: 1024
[partial data...]Return sebagian data aja (range request)
Dipake untuk:
HTTP/1.1 207 Multi-Status
Content-Type: application/xml
<?xml version="1.0"?>
<multistatus xmlns="DAV:">
<response>...</response>
</multistatus>Banyak status buat banyak resource
HTTP/1.1 208 Already ReportedMember udah dilaporin sebelumnya di response yang sama
HTTP/1.1 226 IM Used
IM: vcdiffServer udah fulfill request dengan instance manipulation
Client perlu action lagi buat complete request
HTTP/1.1 300 Multiple Choices
Content-Type: text/html
<ul>
<li><a href="/doc.html">HTML version</a></li>
<li><a href=
Ada banyak pilihan resource
HTTP/1.1 301 Moved Permanently
Location: https://new-domain.com/pageResource pindah permanen ke URL baru
Best practice:
Contoh penggunaan:
// Express.js
app.get('/old-page', (req, res) => {
res.redirect(301, '/new-page');
});HTTP/1.1 302 Found
Location: /temporary-pageResource pindah sementara (temporary redirect)
Kapan dipake:
HTTP/1.1 303 See Other
Location: /success-pageRedirect ke URL lain pake GET method
Use case:
// After form submission
app.post('/submit', (req, res) => {
// Process form...
res.redirect(303, '/success');
});HTTP/1.1 304 Not Modified
ETag: "abc123"
Cache-Control: max-age=3600Resource gak berubah, pake cache aja
Headers yang diperlukan:
If-None-Match (client) + ETag (server)If-Modified-Since (client) + Last-Modified (server)HTTP/1.1 307 Temporary Redirect
Location: /temp-locationKayak 302, tapi method & body gak berubah
Bedanya sama 302:
HTTP/1.1 308 Permanent Redirect
Location: /new-permanent-locationKayak 301, tapi method & body gak berubah
Ada yang salah di sisi client nih
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "Invalid JSON syntax"
}Request gak valid (syntax error, validation error, dll)
Contoh kasus:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"
{
"error": "Token expired"
}Salah kaprah: Ini bukan "unauthorized", tapi "unauthenticated" Artinya: Kamu belum login atau token invalid
Best practice:
// JWT authentication
if (!token || !isValidToken(token)) {
return res.status(401).json({
error: 'Authentication required'
});
}HTTP/1.1 402 Payment RequiredReserved buat future use (payment systems)
HTTP/1.1 403 Forbidden
{
"error": "You don't have permission to access this resource"
}Authenticated tapi gak punya akses (gak boleh)
Bedanya sama 401:
Contoh:
// Kamu udah login, tapi bukan admin
if (!user.isAdmin) {
return res.status(403).json({
error: 'Admin only'
});
}HTTP/1.1 404 Not Found
{
"error": "Resource not found"
}Resource yang kamu cari gak ada
Custom 404:
app.use((req, res) => {
res.status(404).json({
error: 'Endpoint not found',
path: req.path
});
});HTTP/1.1 405 Method Not Allowed
Allow: GET, POST
{
"error": "DELETE method not allowed"
}Method HTTP gak diizinkan buat endpoint ini
HTTP/1.1 406 Not AcceptableServer gak bisa return format yang diminta di Accept header
HTTP/1.1 407 Proxy Authentication Required
Proxy-Authenticate: Basic realm="proxy"Client harus auth ke proxy dulu
HTTP/1.1 408 Request TimeoutClient kelamaan gak kirim request
HTTP/1.1 409 Conflict
{
"error": "Email already exists"
}Conflict sama state resource saat ini
Contoh penggunaan:
// Email udah dipake
if (await User.findOne({ email })) {
return res.status(409).json({
error: 'Email already registered'
});
}HTTP/1.1 410 Gone
{
"error": "This resource has been permanently deleted"
}Resource udah gak ada dan gak akan balik lagi (permanen)
Bedanya sama 404:
HTTP/1.1 411 Length RequiredRequest butuh Content-Length header
HTTP/1.1 412 Precondition FailedPrecondition di headers gak terpenuhi
Contoh:
If-Match header gak cocokIf-Unmodified-Since failedHTTP/1.1 413 Payload Too Large
{
"error": "File size exceeds 10MB limit"
}Request body terlalu gede
Handle di Express:
app.use(express.json({ limit: '10mb' }));HTTP/1.1 414 URI Too LongURL terlalu panjang (biasanya karena query string kegedean)
HTTP/1.1 415 Unsupported Media Type
{
"error": "Only JSON is supported",
"received": "application/xml"
}Content-Type yang dikirim gak didukung
HTTP/1.1 416 Range Not Satisfiable
Content-Range: bytes */10240Range yang diminta gak valid
HTTP/1.1 417 Expectation FailedServer gak bisa fulfill Expect header
HTTP/1.1 418 I'm a teapot
{
"error": "I'm a teapot, not a coffee maker! ☕"
}Easter egg! Dari RFC 2324 (April Fools' joke) Teapot gak bisa brew coffee 😄
HTTP/1.1 421 Misdirected RequestRequest dikirim ke server yang gak bisa produce response
HTTP/1.1 422 Unprocessable Entity
{
"errors": {
"email": "Invalid email format",
"age": "Must be at least 18"
}
}Request valid tapi semantic error (validation failed)
Bedanya sama 400:
Contoh:
// Validation error
const errors = validateUser(req.body);
if (errors.length > 0) {
return res.status(422).json({ errors });
}HTTP/1.1 423 LockedResource terkunci
HTTP/1.1 424 Failed DependencyRequest failed karena request sebelumnya gagal
HTTP/1.1 425 Too EarlyServer gak mau proses request yang mungkin di-replay
HTTP/1.1 426 Upgrade Required
Upgrade: HTTP/2.0Client harus switch ke protokol lain
HTTP/1.1 428 Precondition RequiredRequest harus punya precondition headers
HTTP/1.1 429 Too Many Requests
Retry-After: 3600
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640000000
{
"error": "Rate limit exceeded. Try again in 1 hour"
}Rate limiting! Client request terlalu banyak
Headers yang berguna:
Retry-After: Kapan boleh coba lagiX-RateLimit-Limit: Limit per windowX-RateLimit-Remaining: Sisa quotaX-RateLimit-Reset: Timestamp resetImplementasi:
// Rate limiting middleware
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 menit
max: 100, // max 100 requests
HTTP/1.1 431 Request Header Fields Too LargeHeader fields terlalu besar
HTTP/1.1 451 Unavailable For Legal Reasons
{
"error": "Content blocked due to legal reasons"
}Resource gak bisa diakses karena alasan hukum (censorship, DMCA, dll)
Server yang error, bukan salah lo
HTTP/1.1 500 Internal Server Error
{
"error": "Something went wrong on our end"
}Generic error - Ada yang error di server
Best practice:
app.use((err, req, res, next) => {
console.error(err.stack); // Log di server
res.status(500).json({
error: 'Internal server error'
// Jangan: error: err.message (bisa expose sensitive info)
HTTP/1.1 501 Not Implemented
{
"error": "This method is not supported yet"
}Server gak recognize atau gak support method
HTTP/1.1 502 Bad GatewayServer (sebagai gateway/proxy) dapat invalid response dari upstream server
Contoh kasus:
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
{
"error": "Service temporarily unavailable",
"retry_after": 3600
}Server temporarily gak bisa handle request
Kapan dipake:
Implementasi maintenance:
const MAINTENANCE_MODE = process.env.MAINTENANCE === 'true';
app.use((req, res, next) => {
if (MAINTENANCE_MODE) {
return res.status(503
HTTP/1.1 504 Gateway TimeoutServer (sebagai gateway) gak dapat response dari upstream server tepat waktu
Bedanya sama 502:
HTTP/1.1 505 HTTP Version Not SupportedHTTP version yang dipake gak didukung
HTTP/1.1 506 Variant Also NegotiatesInternal configuration error di content negotiation
HTTP/1.1 507 Insufficient StorageServer gak bisa store representation yang diperlukan
HTTP/1.1 508 Loop DetectedServer detect infinite loop saat proses request
HTTP/1.1 510 Not ExtendedFurther extensions required buat fulfill request
HTTP/1.1 511 Network Authentication Required
{
"error": "Network authentication required"
}Client harus auth buat dapat network access
Contoh: Captive portal di WiFi public
200 OK → Request sukses
201 Created → Resource dibuat
202 Accepted → Async processing
204 No Content → Sukses tapi gak ada data
206 Partial Content → Partial data (streaming)301 Moved Permanently → Permanent redirect
302 Found → Temporary redirect (method bisa berubah)
303 See Other → POST-Redirect-GET
304 Not Modified → Use cache
307 Temporary Redirect → Temporary (method tetap)
308 Permanent Redirect → Permanent (method tetap)400 Bad Request → Syntax/validation error
401 Unauthorized → Gak authenticated
403 Forbidden → Gak authorized
404 Not Found → Resource gak ada
409 Conflict → Duplicate/conflict
422 Unprocessable Entity → Semantic validation error
429 Too Many Requests → Rate limit exceeded500 Internal Server Error → Generic server error
502 Bad Gateway → Invalid upstream response
503 Service Unavailable → Temporary unavailable
504 Gateway Timeout → Upstream timeoutUntuk API endpoints:
// GET - Retrieve data
app.get('/users/:id', async (req, res) => {
Consistent error structure:
// Error response standard
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": [
{
"field"
// 401 - Unauthenticated (belum login)
if (!req.user) {
return res.status(401).json({
error: 'Authentication required',
message: 'Please login first'
});
}
// 403 - Unauthorized (udah login tapi gak boleh)
if
// 304 Not Modified pattern
app.get('/data', (req, res) => {
const data = getData();
const etag = generateETag(data);
// Check if client has latest version
if (req.headers[
// 429 Too Many Requests
const rateLimit = new Map();
function checkRateLimit(userId) {
const now = Date.now
// JANGAN GINI!
app.post('/users', async (req, res) => {
try {
const user = await User.create(req.body);
res.status(200).
app.post('/users', async (req, res) => {
try {
const user = await User.create(req.body);
res.status(201
// SALAH!
if (!user.isAdmin) {
return res.status(401).json({ error: 'Not admin' }); // Harusnya 403
}// Authentication (401)
if (!req.user) {
return res.status(401).json({ error: 'Please login' });
}
// Authorization (403)
if (!req.user.isAdmin) {
return res.status(403
// BAHAYA! Jangan expose stack trace
app.use((err, req, res, next) => {
res.status(500).json({
error: err.message,
stack: err.stack // JANGAN!
});
});app.use((err, req, res, next) => {
// Log di server
console.error(err);
// Return generic message
res.status(500).json({
error: 'Internal server error'
Request diterima
↓
Syntax valid?
├─ No → 400 Bad Request
└─ Yes
↓
Authenticated?
├─ No → 401 Unauthorized
└─ Yes
↓
Authorized?
├─ No → 403 Forbidden
└─ Yes
↓
Resource exists?
├─ No → 404 Not Found
└─ Yes
↓
Method allowed?
├─ No → 405 Method Not Allowed
└─ Yes
↓
describe('User API', () => {
test('POST /users - should return 201 on success', async () => {
describe('Error handling', () => {
test('should return 401 when not authenticated', async () => {
const res = await request