goauthentik / goauthentik/authentik
2026.8.0 crash-loops on startup: TypeError in ensure_allowed_version() ("cannot use a string pattern on a bytes-like object")
- Dominant language
- Python
- Stars
- 25.6k
- Forks
- 2k
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 659
Description
### Describe the bug
Upgrading a Docker Compose deployment from `2026.5.6` to `2026.8.0` causes both `authentik-server` and `authentik-worker` to crash-loop immediately on startup. The crash happens in the pre-migration version-skip check added in #24160 (`ensure_allowed_version()` in `lifecycle/migrate.py`):
```
TypeError: cannot use a string pattern on a bytes-like object
File "/lifecycle/gunicorn.conf.py", line 164, in
run_migrations()
File "/lifecycle/migrate.py", line 135, in run_migrations
ensure_allowed_version(curr)
File "/lifecycle/migrate.py", line 93, in ensure_allowed_version
db_version = Version(cursor.fetchone()[0])
File "/ak-root/.venv/lib/python3.14/site-packages/packaging/version.py", line 436, in __init__
match = self._regex.fullmatch(version)
```
`packaging.version.Version.__init__` calls a compiled `re` pattern's `.fullmatch()` against the value, which only accepts `str`, not `bytes` — hence the `TypeError`. This means `cursor.fetchone()[0]` (the `version` column from `authentik_version_history`) is coming back as `bytes` from the DB driver, even though the column itself is `text`:
```
version | pg_typeof
-----------+-----------
2026.5.6 | text
2026.2.1 | text
2025.12.4 | text
2025.2.4 | text
```
(verified directly against the Postgres database — the `authentik_version_history.version` column is `text`, ruling out a schema/data issue.)
Both `authentik-server` and `authentik-worker` fail identically, since both run this same startup check, and neither ever becomes healthy — the whole deployment goes down.
### How to reproduce
1. Run authentik `2026.5.6` via Docker Compose against an external PostgreSQL instance (not the bundled Postgres container — connecting to a separately managed Postgres host).
2. Confirm `authentik_version_history` has rows from prior upgrades (in our case: `2025.2.4` → `2025.12.4` → `2026.2.1` → `2026.5.6`).
3. Bump the image tag to `2026.8.0` for both `authentik-server` and `authentik-worker`, `docker compose up -d`.
4. Both containers restart forever; `docker logs authentik-server` shows the traceback above.
### Expected behavior
`ensure_allowed_version()` should read the `version` column as `str` (as the column type is `text`) and complete the version-skip check without crashing, allowing normal startup/migration to proceed.
### Screenshots
_No response_
### Version and Deployment (please complete the following information)
- authentik version: 2026.8.0 (upgrading from 2026.5.6)
- Deployment: Docker Compose
- Database: external, self-managed PostgreSQL (not authentik's bundled Postgres container)
### Additional context
- Downgrading `authentik_version` back to `2026.5.6` and redeploying immediately restores a healthy `authentik-server` + `authentik-worker`, confirming this is specific to the `2026.8.0` startup path, not our Postgres instance or data.
- This may be related to how the DB connection is opened in `run_migrations()` / `postgresql_direct_connection_kwargs(CONFIG)` — possibly a binary-format cursor or similar — rather than anything in the schema itself, since the column is confirmed `text` at the database level.
- Happy to provide more log output, `docker compose` config, or test further if it helps narrow this down.
Contributor guide
Assessment
This issue has not been assessed yet.