Jupyter Notebook not saving '_xsrf' argument missing from post
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The '_xsrf' argument missing from POST error in Jupyter Notebook usually appears when the browser sends a save request, upload request, or rename request without the cross-site request forgery token that Jupyter expects. In plain terms, the server no longer trusts the browser session, so it rejects the POST.
This is often caused by stale cookies, mismatched URLs, or a reverse proxy that breaks headers or cookies. The fix is usually to restore a consistent browser session rather than to disable the protection entirely.
What the Error Actually Means
Jupyter uses an XSRF token to ensure that state-changing requests really come from the notebook page you opened. When you click Save, the browser must send the token back in a form Jupyter recognizes.
If that token is missing or no longer matches the cookie stored in the browser, the server rejects the request and logs a message similar to '_xsrf' argument missing from POST.
That is why the notebook may still load in the browser while saving fails. GET requests can work, but protected POST requests fail.
Common Causes
The most common causes are:
- an old browser tab using an expired session
- cookies left over from another Jupyter server on the same host
- accessing the same server through different URLs, such as
localhostin one tab and an IP address in another - a reverse proxy that does not forward headers consistently
- cross-origin embedding or custom front-end code that bypasses Jupyter's normal request flow
A very common real-world case is opening Jupyter through one hostname, then later switching to another route to the same server. The cookie domain and the request origin no longer line up cleanly.
Start with the Easy Fixes
Before changing configuration, try the low-risk fixes first.
- Close all Jupyter tabs.
- Clear cookies for the Jupyter host.
- Reopen the server using one consistent URL.
- Log in again if the server uses a token or password.
If you start Jupyter locally, use the exact URL shown in the terminal instead of mixing hostnames.
Then open the full URL that Jupyter prints, including the token parameter if one is present.
Reverse Proxy Setups Need Correct Headers
If Jupyter is behind Nginx or another proxy, the proxy must forward the request in a way that preserves host and scheme information. A minimal Nginx example looks like this:
On the Jupyter side, configure the base URL if the server is mounted under a path prefix:
If the proxy path and Jupyter base URL disagree, the browser can load the UI but fail when it tries to send authenticated POST requests.
Be Careful with Cross-Origin Configuration
Sometimes developers try to fix the issue by loosening origin rules. That can help in very specific embedded or proxied setups, but it is not the first thing to change.
For example:
This is only appropriate when you intentionally need cross-origin access from a trusted origin. It does not fix stale cookies, and it should not be used as a blanket workaround.
Last Resort: Disable the XSRF Check Only in Controlled Environments
There is a configuration switch to disable the check, but it should be reserved for tightly controlled internal use, temporary debugging, or non-browser automation you fully trust.
Or from the command line:
This removes an important security protection. It may make the symptom disappear, but it does not solve the root cause, and it is a poor default for normal notebook usage.
A Good Mental Model
If reading notebooks works but saving fails, think "session integrity problem," not "notebook file system problem." The server is usually healthy enough to read files. What is broken is the trust relationship between the browser and the server for POST requests.
That mindset helps you focus on cookies, URLs, proxy behavior, and Jupyter config instead of wasting time debugging notebook permissions on disk.
Common Pitfalls
- Disabling XSRF protection immediately instead of checking cookies and URL consistency first.
- Opening the same Jupyter server through multiple hostnames and mixing browser sessions.
- Forgetting to align
base_urlwith the reverse proxy path prefix. - Using proxy settings that do not forward host and scheme information correctly.
- Assuming a save failure means the notebook file is read-only when the real issue is a rejected POST.
Summary
- The error means Jupyter rejected a protected POST because the XSRF token was missing or mismatched.
- Start by clearing cookies, closing stale tabs, and reopening the server with one consistent URL.
- In proxied setups, make sure proxy headers and Jupyter
base_urlsettings match. - Use
allow_originonly for deliberate cross-origin setups, not as a generic fix. - Disable XSRF checks only as a controlled last resort, not as the normal solution.

