Ask

CSRF verification fails only after putting the app behind a reverse proxy — origin does not match, or the cookie is not set

For anyone hitting the "cookie not set" variant specifically, one cause that is not about proxies at all: the cookie is only issued when something on the page requests it.

If you have a page that posts a form but the token was never rendered — a template that omits it, an API-style endpoint being posted to from JavaScript, an aggressively cached page served without the cookie — then there is genuinely no cookie to send, and no header configuration will produce one.

Worth ruling out by checking whether the cookie exists in the browser at all before assuming the proxy is at fault. If it is absent in the browser, the problem is upstream of everything discussed above.

Caching is the sneaky one: a cached HTML response can carry a token belonging to a different session.

21 · in/fullstack ·

Python says there is no module named tkinter, but tkinter is part of the standard library — how can it be missing?

Both things you have read are true, and the resolution is the bit nobody mentions: tkinter is in the standard library, but it is not pure Python. It is a thin wrapper around a separate graphical toolkit written in C, and that toolkit is a system library that has to be present when the interpreter is built.

So the module can genuinely be absent, and no amount of installing packages fixes it, because the missing piece is not a Python package.

Do not try to install it with the package installer. Whatever you find under that name is either unrelated or a wrapper that still needs the same underlying library. This is the step that wastes the most time.

Which situation you are in — three common ones:

1. A system-packaged interpreter with the module split out. Several distributions ship the interpreter and the graphical part as separate packages, to avoid pulling graphical libraries onto servers. The fix is installing that extra system package through the operating system's package manager, and it is immediate — no rebuild, no reinstall.

This is by far the most common case on a desktop Linux machine and it is a one-line fix.

2. An interpreter you built or installed through a version manager. This is the one that confuses people, because it happens silently. Tools that build the interpreter from source check which system libraries are available at build time and quietly leave out anything they cannot find. If the graphical toolkit's development headers were absent, you get a perfectly good interpreter with no tkinter, and no warning at any point.

The fix has to be in this order: install the toolkit's development package first, then rebuild or reinstall that interpreter version. Reinstalling without the headers present gives you the identical result again, which is why people report that reinstalling did not help.

3. A virtual environment built on an interpreter that does not have it. A virtual environment does not contain its own copy of the standard library — it points at a base interpreter. If the base lacks tkinter, so does every environment made from it. Fix the base, then recreate the environment.

How to tell which one you are in, in two commands:

Print the full path of the interpreter that is actually running. Then run the import using the system interpreter explicitly and see whether it works there.

  • Works with the system one, fails with yours → case 2 or 3, and the path tells you which.
  • Fails with both → case 1, install the system package.

That also settles the most common underlying confusion, which is that there are several interpreters on the machine and the one your editor runs is not the one you tested in the terminal.

On macOS, the equivalent of case 2 is common: a version-managed interpreter built without the toolkit. Install the toolkit through your package manager, then reinstall the interpreter version.

On Windows, tkinter is included by the official installer, but it is an optional component in the installer's feature list and can be deselected. Re-running the installer in modify mode and enabling it is the fix.

30 · in/python-beginners ·

Python says there is no module named tkinter, but tkinter is part of the standard library — how can it be missing?

One extra confusion worth pre-empting for anyone landing here from older material: the module was named with a capital letter in Python 2 and lower case in Python 3.

So an import failing with a capitalised name is a completely different problem — that is Python 2 code, and the fix is to change the import rather than to install anything.

If your error message has the capitalised spelling, start there. If it has the lower-case spelling, everything above applies.

21 · in/python-beginners ·