---
id: start.middleware-chain
kind: contract
product: start
framework: react
locale: en
revision: 2
sourceCheckedOn: "2026-08-03"
versionRange: "^1"
verifiedAgainst: "@tanstack/react-start@1.168.34"
contentModel: 2
packages:
  - "@tanstack/react-start"
tasks:
  - "create-middleware"
  - "compose-server-function-middleware"
  - "choose-middleware-scope"
sourceRefs:
  - "https://tanstack.com/start/latest/docs/framework/react/guide/middleware"
  - "https://tanstack.com/start/latest/docs/framework/react/guide/server-functions"
---

# Establish a Start Middleware chain

> Define request and function scopes, compose context through next(), and preserve authentication and CSRF boundaries.

## Execution contract

- **Use when:** Use when server functions, routes, or requests share logging, auth, context, or timing behavior.
- **Avoid when:** Keep one-off business logic in its handler or domain service when it has no cross-cutting reuse.
- **Preconditions:** Choose middleware type, order, context input/output, and how next() propagates errors.
- **Verification:** Test ordering, short-circuiting, errors, and concurrent requests to ensure per-request context isolation.
- **Failure mode:** A skipped handler or missing context usually means next() was not returned, ordering is wrong, or middleware type mismatches.
- **Security:** Logging middleware must redact cookies, Authorization, secrets, and sensitive request bodies.

## Scope contract

createMiddleware() creates request middleware by default for SSR, Server Routes, and Server Functions. createMiddleware({ type: 'function' }) creates Server Function middleware with validator and client phases. Do not promote a function-local rule to a global request rule merely for reuse.

## Chain implementation

Call next to execute downstream code and return its result. Fields added with next({ context }) flow downstream only. An early return should be an intentional rejection or response, not a missing next call.

File: `src/server/request-context.ts`

```ts
import { createMiddleware } from '@tanstack/react-start'

export const requestIdMiddleware = createMiddleware()
  .server(({ next }) => next({
    context: { requestId: crypto.randomUUID() },
  }))
```

## Security invariants

Client sendContext is untrusted input: validate it on the server and never use it as identity itself. After adding a custom src/start.ts, explicitly retain createCsrfMiddleware. CSRF, input validation, authentication, and resource authorization are separate checks.

## Official sources

- https://tanstack.com/start/latest/docs/framework/react/guide/middleware
- https://tanstack.com/start/latest/docs/framework/react/guide/server-functions
