
August 14, 2026
9 min read
Table of Contents
By Kokil Thapa | Last reviewed: August 2026
Inconsistent JSON error responses break client integrations and waste developer time debugging ambiguous messages. Adopting API Error Handling RFC 7807 Problem Details gives your Laravel or Symfony API a standardised, machine-readable error structure that both humans and automated clients can parse reliably. If you are building public APIs or integrating payment gateways like eSewa or Khalti, this specification removes guesswork from failure states and aligns your stack with modern REST best practices outlined in our Laravel API best practices guide.
What Is API Error Handling RFC 7807 Problem Details and Why Use It?
RFC 7807, updated by RFC 9457 in 2023 but still universally referred to by its original number, defines a simple JSON object for conveying error information in HTTP APIs. The core value proposition is predictability. Before this standard, every API invented its own error shape: some used { "error": "..." }, others { "message": "...", "code": 400 }, and legacy systems sometimes returned HTML error pages even for JSON requests. This fragmentation forces every client developer to write custom parsers for each service they consume.
The specification mandates the content type application/problem+json. This signals to HTTP clients, proxies, and monitoring tools that the body contains structured problem metadata rather than arbitrary application data. The five standard members are:
- type (string): A URI reference identifying the specific error category. This should be stable and dereferenceable to human documentation.
- title (string): A short, human-readable summary of the error type. Should not change between occurrences of the same error.
- status (integer): The HTTP status code generated by the origin server.
- detail (string): A human-readable explanation specific to this occurrence.
- instance (string): A URI reference identifying the specific resource or request occurrence, useful for tracing logs.
In my experience shipping legal-tech portals and eCommerce platforms in Nepal, adopting this format reduced support tickets related to "unclear API errors" significantly. When integrating with Nepali payment providers or government verification services, having a predictable error contract makes debugging webhook failures and callback rejections far faster. For teams hiring junior developers or outsourcing frontend work, as discussed in hiring web developers in Nepal, a standard error format reduces onboarding friction because new team members don't need to learn proprietary error schemas.
How Do You Implement API Error Handling RFC 7807 Problem Details in Laravel 12?
Laravel 12 (requiring PHP 8.2 minimum) does not ship RFC 7807 responses out of the box; the default exception renderer returns { "message": "..." } for JSON requests. You must override this behaviour centrally. The cleanest approach in 2026 is using the withExceptions() callback in bootstrap/app.php or a dedicated Exception Handler class if you prefer the traditional structure.
Step 1: Create a Problem Details Response Builder
Create a reusable builder so you never manually construct arrays. This enforces consistency and makes testing straightforward.
<?php
// app/Support/ProblemDetails.php
namespace App\Support;
use Illuminate\Http\JsonResponse;
class ProblemDetails
{
public static function respond(
string $type,
string $title,
int $status,
string $detail = '',
string $instance = '',
array $extensions = []
): JsonResponse {
$payload = array_filter([
'type' => $type,
'title' => $title,
'status' => $status,
'detail' => $detail,
'instance' => $instance ?: request()->path(),
], fn ($v) => $v !== '');
return response()->json(
array_merge($payload, $extensions),
$status,
['Content-Type' => 'application/problem+json']
);
}
} Step 2: Register Global Exception Mapping
In Laravel 12's streamlined configuration, map common exceptions to RFC 7807 responses inside bootstrap/app.php:
->withExceptions(function (Exceptions $exceptions) {
$exceptions->render(function (ValidationException $e) {
return ProblemDetails::respond(
type: 'https://api.example.com/errors/validation-failed',
title: 'Validation Failed',
status: 422,
detail: 'One or more fields failed validation.',
extensions: ['errors' => $e->errors()]
);
});
$exceptions->render(function (NotFoundHttpException $e) {
return ProblemDetails::respond(
type: 'https://api.example.com/errors/resource-not-found',
title: 'Resource Not Found',
status: 404,
detail: $e->getMessage() ?: 'The requested resource does not exist.'
);
});
$exceptions->render(function (Throwable $e) {
if (request()->expectsJson()) {
return ProblemDetails::respond(
type: 'https://api.example.com/errors/internal-error',
title: 'Internal Server Error',
status: 500,
detail: app()->hasDebugModeEnabled() ? $e->getMessage() : 'An unexpected error occurred.'
);
}
});
}) This pattern ensures every JSON client receives API Error Handling RFC 7807 Problem Details regardless of which controller throws. Note the security guard on 500 errors: never leak stack traces or internal paths in production. On legal-tech projects handling sensitive case data, I always strip internal details from production error responses while keeping them available in local/staging environments for debugging.
How Does RFC 7807 Compare to Traditional API Error Formats?
Many teams hesitate to adopt a new standard because existing clients expect legacy formats. Understanding the concrete trade-offs helps justify the migration cost. Below is a comparison based on real migrations I've performed on Laravel APIs serving both mobile apps and third-party integrators.
| Criteria | Legacy Custom Format | RFC 7807 Problem Details |
|---|---|---|
| Content Negotiation | Ambiguous; often application/json | Explicit application/problem+json |
| Client Parsing | Custom parser per API vendor | Generic parser works across services |
| Documentation Linkage | Manual lookup required | type URI links directly to docs |
| Extensibility | Ad-hoc; breaks contracts | Defined extension mechanism |
| Tooling Support | None; manual inspection | Postman, Insomnia, OpenAPI native support |
| Migration Effort | N/A | Moderate; requires client updates |
| SEO / Crawlability Impact | Search engines may misinterpret errors | Clear semantic signal for crawlers |
The SEO row deserves attention. While APIs aren't typically indexed, public-facing hybrid sites (like legal information portals) sometimes serve JSON-LD or structured content alongside API endpoints. Consistent error semantics prevent search engines from indexing error states as valid content. This aligns with technical SEO audits covered in our technical SEO audit guide for Nepal, where proper HTTP semantics form part of crawl health.
What Are Common Mistakes When Implementing RFC 7807 in Production?
I've reviewed dozens of API implementations during code audits and migrations. These anti-patterns appear repeatedly and undermine the benefits of standardisation.
- Omitting the Content-Type header. Returning the correct JSON shape with
application/jsondefeats the purpose. Clients checking headers will treat it as generic data. Always setapplication/problem+jsonexplicitly. - Using dynamic strings in the
typefield. The type URI should be a stable identifier likehttps://api.example.com/errors/validation-failed, not/errors/val-err-2026-08-14. Dynamic types break client routing logic and documentation links. - Leaking sensitive data in
detail. Database column names, file paths, SQL fragments, and user IDs have no place in production error responses. Sanitise aggressively. On legal-tech systems, this is non-negotiable due to client confidentiality obligations. - Ignoring the
instancefield. This field exists for correlation. Populate it with the request path, trace ID, or transaction reference. When debugging payment gateway callbacks at 2 AM, being able to grep logs by instance value saves hours. - Over-engineering extension properties. Only add custom fields when clients programmatically need them. Adding
user_id,server_region, ordebug_trace"just in case" creates maintenance burden and potential privacy issues. - Inconsistent adoption across endpoints. Mixing RFC 7807 responses with legacy formats in the same API confuses clients. Migrate atomically or version the API. Partial adoption is worse than no adoption.
How Do You Test and Validate RFC 7807 Responses Automatically?
Manual curl checks don't scale. Build validation into your test suite and CI pipeline. In Laravel 12 with PHPUnit or Pest, assert both structure and content type:
it('returns RFC 7807 validation error', function () {
$response = $this->postJson('/api/v1/cases', [
'client_name' => '', // invalid
]);
$response->assertStatus(422)
->assertHeader('Content-Type', 'application/problem+json')
->assertJsonStructure([
'type',
'title',
'status',
'detail',
'instance',
'errors', // extension
])
->assertJsonFragment([
'type' => 'https://api.example.com/errors/validation-failed',
'title' => 'Validation Failed',
]);
}); For integration tests hitting real staging environments, consider writing a reusable assertion macro. Also validate that non-JSON requests (e.g., browser navigation) still receive appropriate HTML error pages — RFC 7807 applies only when the client signals JSON acceptance via Accept header or URL suffix.
On projects using OpenAPI/Swagger, document problem details responses explicitly in your spec. Tools like Stoplight and Scalar render these beautifully for frontend consumers. When working with international clients or documenting APIs for outsourced teams, as many Nepal-based agencies do, this documentation becomes the single source of truth that prevents miscommunication.
Practical Next Steps for Your API
Implementing API Error Handling RFC 7807 Problem Details is a one-day investment that pays dividends across every future integration. Start by creating the response builder utility shown above, then migrate your exception handler incrementally. Prioritise high-traffic endpoints and authentication flows first, as these generate the most client-side error handling code. Remember to update your API documentation and notify existing consumers before switching content types in production.
If you're building or refactoring APIs in Laravel or Symfony and want hands-on guidance tailored to your stack, reach out through my contact page. Whether you're integrating Nepali payment gateways, building legal-tech platforms, or modernising legacy systems, getting error handling right early prevents costly rewrites and support overhead later.

