reflex-dev/reflex · error · HTTPException

Missing reflex-client-token or reflex-event-handler header.

Error message

Missing reflex-client-token or reflex-event-handler header.

What it means

The upload endpoint requires two headers to route and authorize a streaming upload: reflex-client-token (ties the upload to the client's state token) and reflex-event-handler (which handler to dispatch). Missing either yields HTTP 400 before parsing starts.

Source

Thrown at packages/reflex-components-core/src/reflex_components_core/core/_upload.py:514


def _require_upload_headers(request: Request) -> tuple[str, str]:
    """Extract the required upload headers from a request.

    Args:
        request: The incoming request.

    Returns:
        The client token and event handler name.

    Raises:
        HTTPException: If the upload headers are missing.
    """
    token = request.headers.get("reflex-client-token")
    handler = request.headers.get("reflex-event-handler")

    if not token or not handler:
        raise HTTPException(
            status_code=400,
            detail="Missing reflex-client-token or reflex-event-handler header.",
        )

    return token, handler


# Multipart form field carrying the JSON-encoded extra bound handler args.
# Uploads travel over a REST endpoint instead of the socket, so args bound to
# the handler (e.g. ``State.on_drop(rx.upload_files(...), field)``) ride in this
# field. Kept in sync with the matching literal in the web upload template.
UPLOAD_EVENT_ARGS_FIELD = "__reflex_event_args"

# Cap on the buffered bound-args field for streaming uploads. The args are small
# identifiers, so this only bounds the in-memory buffer against a hostile client
# (file parts are backpressured via the chunk iterator; this field is not).
MAX_UPLOAD_EVENT_ARGS_BYTES = 1024 * 1024

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Include both headers: reflex-client-token: <token> and reflex-event-handler: <state.handler_name> in upload requests
  2. Use rx.upload / the generated JS client which sets these automatically
  3. Check proxy/CORS config allows and forwards the custom reflex-* headers

Example fix

# before
curl -X POST http://app/_upload -F files=@a.txt

# after
curl -X POST http://app/_upload \
  -H 'reflex-client-token: <token>' \
  -H 'reflex-event-handler: state.handle_upload' \
  -F files=@a.txt
Defensive patterns

Strategy: validation

Validate before calling

headers = {"reflex-client-token": token, "reflex-event-handler": handler}
assert all(headers.values())

Prevention

When it happens

Trigger: POSTing to the upload URL without one or both of the reflex-client-token / reflex-event-handler headers — custom clients, curl tests, or proxies stripping custom headers.

Common situations: Custom upload scripts replicating the Reflex client; CORS proxies stripping custom X-/reflex- headers; older Reflex JS client version sending different header names after an upgrade.

Related errors


AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28). Data as JSON: /api/errors/2808e6f8434c339f. Report an issue: GitHub.