You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] WebSocket callbacks do not expose request cookies/headers on callback_context #3814
Backend: FastAPI (Dash(name, backend="fastapi")); the same issue exists for the Quart backend.
Describe the bug
When a callback runs over the WebSocket transport (declared with websocket=True, or via websocket_callbacks=True), the request cookies and headers are not available on dash.callback_context. They are empty.
The HTTP transport populates these correctly (via Dash._initialize_context), but the WebSocket context builder (create_ws_context in dash/backends/ws.py) never sets cookies, headers, args, path, remote, or origin.
This breaks any authentication helper that reads the request context. In our case, running our apps on Dash Enterprise, dash_enterprise_auth.get_user_data() reads the kcIdToken cookie (or the Plotly-User-Data header on older Dash Enterprise) from callback_context.cookies. Over WebSocket it receives {}.
Steps to reproduce
fromdashimportDash, html, dcc, Input, Output, ctxapp=Dash(__name__, backend="fastapi")
app.layout=html.Div([
dcc.Input(id="q", type="text"),
html.Div(id="out"),
])
@app.callback(Output("out", "children"), Input("q", "value"), websocket=True)defshow_cookies(value):
# Over HTTP this is populated; over WebSocket it is empty.returnf"cookies={dict(ctx.cookies)} headers={bool(ctx.headers)}"if__name__=="__main__":
app.run(debug=True)
Run the app and open it in a browser (so the request carries cookies).
Type into the input to trigger the websocket=True callback.
Observe ctx.cookies is {} and ctx.headers is empty.
Change the callback to a normal HTTP callback (remove websocket=True) and observe the cookies/headers are present.
Expected behavior
callback_context.cookies and callback_context.headers (and args, path, remote, origin) should be populated for WebSocket callbacks just as they are for HTTP callbacks, so authentication/session helpers behave consistently across transports.
Actual behavior
callback_context.cookies/headers are empty for WebSocket callbacks, causing auth helpers such as dash_enterprise_auth.get_user_data() to fail.
Root cause
create_ws_context in dash/backends/ws.py builds the callback context but omits the request metadata that Dash._initialize_context sets for the HTTP path. The WebSocket handshake request (which carries the cookies/headers) is available in the backend WebSocket handlers (_fastapi.py / _quart.py) but is never forwarded into the context.
Would it make sense to pass the WebSocket object directly into the callback context? I was thinking specifically of accessing the websocket.session if using session middleware.
Websockets do not use cookies and headers, there is a different methodology for this. As this would just initially drift throughout the lifecycle of the websocket. You'll need to determine if you want to build your own auth method for the websocket flow to protect it, and extend it out from there.
You can also use your own custom_data hook that can attach to the callback.
That's reasonable. For my use-case I've since extended dash_enterprise_auth to cover websocket callbacks to solve this via the standard "server-side session token" pattern, and no longer need the request context.
Do you suggest I close this issue & close my PR? (#3815)
Activity
Huaian666 commentedon Jun 12, 2026
hit this in prod last week 😬 had to roll back. any timeline on a fix?
andredfb commentedon Jun 19, 2026
Would it make sense to pass the WebSocket object directly into the callback context? I was thinking specifically of accessing the websocket.session if using session middleware.
BSd3v commentedon Jun 26, 2026
@Huaian666 and @i-murray,
Websockets do not use cookies and headers, there is a different methodology for this. As this would just initially drift throughout the lifecycle of the websocket. You'll need to determine if you want to build your own auth method for the websocket flow to protect it, and extend it out from there.
You can also use your own
custom_datahook that can attach to the callback.i-murray commentedon Jun 27, 2026
@BSd3v
That's reasonable. For my use-case I've since extended
dash_enterprise_authto cover websocket callbacks to solve this via the standard "server-side session token" pattern, and no longer need the request context.Do you suggest I close this issue & close my PR? (#3815)
AnnMarieW commentedon Jul 8, 2026
Hi @i-murray
Glad you found an alternate solution.
Closing this issue since PR 3815 has been closed.