## TL;DR
notebook 6.4 pins tornado below 6.2, so an environment where tornado got upgraded to 6.2 anyway crashes the server on startup. Resolve it in one direction: either `pip install -U notebook` (which resolves to 6.5 or newer, past the pin) or `pip install "tornado==6.1"` to honor the old pin. Verify with `jupyter notebook --version` and a clean server start.

```text
tornado 6.2 incompatible with notebook 6.4, how to fix the crash
```

## Use this when
- The notebook server crashes on startup after tornado reached 6.2.
- The traceback shows tornado import or websocket errors inside notebook 6.4 code.
- A requirements file pins notebook 6.4 without pinning tornado.

## Not for this skill when
- JupyterLab (not notebook 6.x) is crashing. Check its own tornado range.
- Kernels die. Tornado is server-side; kernel crashes are separate.

## Steps
1. Confirm the pair: `pip show tornado notebook | grep -E "Name|Version"`. Verify: tornado 6.2 with notebook 6.4.
2. Preferred: upgrade notebook out of the pinned range with `pip install -U notebook` (resolves to 6.5+). Verify: the version is 6.5+.
3. Alternative: pin tornado back with `pip install "tornado==6.1"`. Verify: tornado reports 6.1.x.
4. Start the server: `jupyter notebook --no-browser`. Verify: it serves without a traceback.
5. Record the working pair in your requirements file. Verify: a fresh install reproduces the working combination.

## Variant phrasings
### tornado notebook version conflict
General phrasing. The pair must be compatible.

### notebook 6.4 crash tornado
Version-tagged phrasing. Upgrade notebook past 6.4.

### jupyter server tornado incompatibility
Server-side phrasing. Same pin or upgrade.

Compatibility: notebook 6.4/6.5, tornado 6.1/6.2. notebook 7 uses jupyter_server and has its own compatible ranges.

## Why it happens
notebook 6.4 declared an upper bound on tornado because tornado 6.2 changed internals the old server code depended on. Resolvers that ignore or override the bound, or installs that upgrade tornado independently, produce a server whose imports fail at startup. It is a packaging conflict, not a code bug, so the fix is entirely in version selection.

## Edge cases / pitfalls
- Upgrading tornado alone again later re-breaks it. Pin the pair in requirements, not just one side.
- notebook 6.5+ still has other old pins; upgrading notebook can surface the next conflict. Upgrade deliberately.
- If you actually want modern Jupyter, migrate to notebook 7 or JupyterLab instead of nursing 6.4 pins.
- Conda may refuse the combination its solver cannot satisfy. Let conda pick the pair with `conda install notebook` unpinned.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_-Z6dVWIziX808k5Buu71SQ
