Great work!

XP to next level

BugEater

Provoking and Documenting 500 Errors

Learning Objectives

By the end of this lesson you will be able to:

  • Apply a systematic set of input techniques to provoke 500 errors
  • Distinguish what makes a 500 error different from a 422 or 400 error
  • Document a 500 error so it is reproducible by a developer who was not present when it occurred
  • Reconstruct a 500 scenario from just an error ID when steps to reproduce are unknown

Why Provoking 500 Errors Is a QA Responsibility

A 500 Internal Server Error means the server encountered a condition it did not anticipate. Every 500 is an unhandled case — a gap in the application's defensive coding. QA's job is to find these gaps before real users do. The good news: most 500 errors follow predictable patterns that a methodical set of test inputs can expose.

Input Techniques That Reliably Provoke 500 Errors

Boundary Date Values

The most effective single category for date-handling systems:

  • Year 9999: 9999-12-31 — tests the upper boundary of 4-digit year storage
  • Overflow boundary: 2038-01-19 03:14:08 — the 32-bit Unix timestamp overflow point
  • Pre-epoch dates: 1900-01-01 or 1969-12-31 — tests systems that reject dates before 1970
  • Far future: 2099-12-31 — checks business-range limits

Malformed and Null Date Strings

  • Empty string: "" in a required date field
  • The word "null": "null" or null (JSON) — tests null handling paths
  • Wrong format: "31/12/2024" when ISO 8601 is expected
  • Random text: "not-a-date", "yesterday", "soon" — triggers parse failures
  • Partial date: "2024-", "2024-13" — tests partial input handling

Oversized and Extreme Values

  • Extremely long strings: a 10,000-character string in a date field
  • Integer where string expected: 20241231 (no hyphens) or 1700000000000 (millisecond timestamp)
  • Negative year: "-2024-01-01" — often not covered by validation

Structural Attacks

  • Missing required fields: omit the date entirely from a required field
  • Wrong content type: send Content-Type: text/plain when application/json is expected
  • Truncated JSON: {"start_date": "2024-01-} — unclosed string triggers JSON parse exception before date validation

The Difference Between 500 and 422

A 422 Unprocessable Entity means the server understood the request, parsed it, but the data failed business or format validation. The server handled this case — it returned an error on purpose.

A 500 Internal Server Error means the server did NOT handle the case. The code threw an exception that no error handler caught. When a 500 occurs where a 422 was expected, a bug exists regardless of the input. The input may be "invalid," but the server's job is to return a 400-range error, not to crash.

Documenting a 500 Error for Reproducibility

A 500 bug report must include everything a developer needs to reproduce the crash without asking follow-up questions:

Title: POST /api/bookings returns 500 for empty string in start_date field

Severity: High

Steps to Reproduce:
1. Send: POST /api/bookings
   Headers: Content-Type: application/json, Authorization: Bearer <token>
   Body: {"start_date": "", "end_date": "2024-12-31", "room_id": 5}
2. Observe response.

Expected: 400 Bad Request with validation message
Actual: 500 Internal Server Error
Response body: {"error": "Internal Server Error"}

Environment: Staging — https://staging.example.com
Date/Time: 2024-11-14 14:32:11 UTC
Error ID (if present): err-9f3a12b4

Reconstructing a 500 From an Error ID

When you only have an error ID (from a production log alert or a user complaint), and you cannot reproduce it immediately:

  1. Give the error ID to the developer — they can look it up in the log aggregation system (Datadog, Splunk, CloudWatch) to find the full stack trace and the original request payload.
  2. Note the timestamp — log systems can filter by time, and the timestamp narrows the search even if the ID was not captured.
  3. Identify the correlation pattern — if multiple users hit the same 500, the logs will show the common request structure.

Once the developer identifies the root cause from logs, you can write a proper reproduction test case to prevent regression.

Summary

Provoking 500 errors is a structured discipline, not random fuzzing. A targeted set of boundary dates, null values, malformed strings, and structural anomalies will surface the majority of unhandled exception paths. Documenting them precisely — with raw request/response and an error ID — is what turns a one-time crash observation into a reproducible, fixable bug report.

Quiz

Which type of input most reliably triggers a 500 error in a date field?

What must be captured when documenting a 500 error so the report is useful to a developer?

A 500 error occurred in production, and you only have the error ID (err-9f3a12b4). How do you make this bug reproducible?

How does a 500 error differ from a 422 when a user submits an invalid date?