# Error pages

> Source: https://ferron.sh/docs/use-cases/traffic/error-pages

Custom error pages make failures clearer for users and reduce confusion during incidents. Ferron can serve custom pages for local errors and (with error interception enabled) upstream proxy errors.

## Custom pages for common errors

```ferron
example.com {
    root /var/www/html

    error_page 404 /var/www/custom/404.html
    error_page 500 502 503 504 /var/www/custom/50x.html
}
```

You can map multiple status codes to the same error page in a single directive.

### Including trace information

Set `error_page_placeholders true` to enable `{{trace.id}}` and `{{trace.spanid}}` placeholders in your error page files. When a request triggers an error, Ferron replaces the placeholders with the trace context of the request. This happens before Ferron serves the page.

```ferron
example.com {
    error_page 500 /custom/50x.html
    error_page_placeholders
}
```

Example `50x.html`:

```html
<!DOCTYPE html>
<html>
<head><title>Internal Server Error</title></head>
<body>
    <h1>Something went wrong</h1>
    <p>Trace ID: {{trace.id}}</p>
</body>
</html>
```

> [!note]
> Placeholder substitution reads the file into memory, disabling the zerocopy/sendfile optimization for that response. This is negligible for typical error pages.

## Better UX for upstream failures

When reverse proxying, enable error interception so Ferron can serve custom pages for backend errors:

```ferron
app.example.com {
    location / {
        proxy http://127.0.0.1:3000 {
            intercept_errors
        }
    }

    error_page 502 /custom/502.html
    error_page 503 /custom/503.html
    error_page 504 /custom/504.html
}
```

> [!note]
> The file path is absolute or relative to the current working directory. If the specified error page file does not exist, Ferron skips the directive and uses the built-in error page instead.

## JSON error responses

You can serve JSON error responses using the `json_errors` directive (for example for RESTful APIs):

```ferron
api.example.com {
    json_errors
}
```