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
- Include both headers: reflex-client-token: <token> and reflex-event-handler: <state.handler_name> in upload requests
- Use rx.upload / the generated JS client which sets these automatically
- 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
- Use the built-in Reflex upload client
- Ensure proxies/CORS pass through reflex-* headers
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
- Malformed upload event args.
- Upload event args must be a JSON object.
- @rx.event(background=True) is not supported for upload handl
- `{handler_name}` handler should have a parameter annotated a
- StopAsyncIteration
AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28).
Data as JSON: /api/errors/2808e6f8434c339f.
Report an issue: GitHub.