# How Nitter Handles Malformed URL Paths in Requests: 400 Bad Request vs 404 Not Found

> Discover how Nitter handles malformed URL paths. Learn when Nitter returns a 400 Bad Request versus a 404 Not Found for invalid requests.

- Repository: [Zed/nitter](https://github.com/zedeus/nitter)
- Tags: internals
- Published: 2026-08-29

---

**When Nitter receives a request, it immediately validates the URL path in `src/nitter.nim`, returning a 400 Bad Request for empty paths or those lacking a leading forward slash, and a 404 Not Found for well-formed paths that do not match any defined route.**

Nitter, the open-source Twitter front-end written in Nim, employs strict validation logic to handle **malformed URL paths in Nitter requests** before any routing occurs. This early validation ensures that syntactically invalid requests are rejected immediately, while legitimate-looking URLs that match no endpoint receive appropriate error responses. The implementation details reside primarily in `src/nitter.nim`, where the server distinguishes between protocol-level path errors and application-level missing resources.

## Immediate Path Validation in src/nitter.nim

The server core performs two critical checks on every incoming request path before routing begins.

### Empty Path and Leading Slash Validation

At lines 81-83 of `src/nitter.nim`, Nitter checks if the request path is empty or fails to start with `/`:

```nim
if request.path.len == 0 or request.path[0] != '/':
  halt Http400

```

If either condition is true, the server immediately halts processing and returns **400 Bad Request**. This prevents the router from attempting to process malformed paths that violate HTTP URL standards.

### Static File Path Exclusion

Immediately following the basic validation, lines 84-86 filter out requests that appear to target static files:

```nim
cond "." notin request.path or request.path == "/embed/Tweet.html"

```

This condition strips paths containing dots (which typically indicate file extensions) unless the path is exactly [`/embed/Tweet.html`](https://github.com/zedeus/nitter/blob/main//embed/Tweet.html), a special endpoint for Twitter widget compatibility. Paths blocked here do not proceed to the router, effectively acting as an additional validation layer.

## Routing Failures and 404 Handling

Once a path passes initial validation, Nitter attempts to match it against defined routes in `src/routes/*.nim`.

### The Generic 404 Handler

If no route matches the validated path, execution falls through to the generic error handler at lines 105-107 of `src/nitter.nim`:

```nim
error Http404:
  resp Http404, showError("Page not found", cfg)

```

This handler returns **404 Not Found** with a rendered error page, distinguishing these requests from syntactically malformed URLs that triggered the earlier 400 response.

### Route-Specific Not Found Responses

Individual route handlers in files like `src/routes/timeline.nim`, `src/routes/status.nim`, and `src/routes/search.nim` can also return `Http404` when a requested resource (such as a specific tweet or user) does not exist, though this occurs after successful path validation.

## Testing URL Validation Behavior

You can observe these behaviors using standard HTTP clients. The following examples demonstrate how Nitter responds to various **malformed URL paths in Nitter requests**:

```bash

# Empty path triggers 400 Bad Request

curl -i http://nitter.localhost

# HTTP/1.1 400 Bad Request

# Missing leading slash triggers 400

curl -i http://nitter.localhost"about"

# HTTP/1.1 400 Bad Request

# Valid path format with no matching route triggers 404

curl -i http://nitter.localhost/unknown_route

# HTTP/1.1 404 Not Found

```

## Key Source Files for Request Handling

Understanding the complete request validation pipeline requires familiarity with these components:

- **`src/nitter.nim`**: Contains the core validation logic (400 checks) and generic 404 handler
- **`src/routes/*.nim`**: Individual route definitions that return 404 for missing resources
- **`src/apiutils.nim`**: Handles API-level 404 responses for external Twitter API calls
- **`src/config.nim`**: Provides configuration for error rendering helpers like `showError`

## Summary

- **Malformed syntax triggers 400**: Empty paths or those without a leading `/` receive an immediate 400 Bad Request in `src/nitter.nim`
- **Valid but unmatched paths trigger 404**: Well-formed URLs that match no route fall back to the generic 404 handler at lines 105-107
- **Static files are filtered early**: Paths containing dots are excluded unless they match the specific [`/embed/Tweet.html`](https://github.com/zedeus/nitter/blob/main//embed/Tweet.html) endpoint
- **Validation precedes routing**: All checks occur before any route-specific logic executes, ensuring robust error handling

## Frequently Asked Questions

### What causes Nitter to return a 400 Bad Request?

Nitter returns **400 Bad Request** when the URL path is empty or does not begin with a forward slash, as enforced by the validation logic at lines 81-83 of `src/nitter.nim`. This prevents the router from processing syntactically invalid request paths.

### When does Nitter return 404 Not Found instead of 400?

Nitter returns **404 Not Found** when the URL path passes basic validation (starts with `/` and is not empty) but does not match any defined route in the application. This is handled by the generic error block at lines 105-107 of `src/nitter.nim`.

### How does Nitter handle URLs containing file extensions?

Nitter strips request paths containing dots (indicating potential static files) unless the path exactly matches [`/embed/Tweet.html`](https://github.com/zedeus/nitter/blob/main//embed/Tweet.html). This filtering occurs immediately after the leading slash check in `src/nitter.nim` and prevents static file requests from reaching the dynamic router.

### Where is the error response formatting defined in Nitter?

Error responses utilize the `showError` helper function, which relies on configuration defined in `src/config.nim`. The actual HTTP status codes (400 and 404) and their immediate handlers are defined directly in `src/nitter.nim`, while route-specific 404 responses are generated within individual route files under `src/routes/`.