v0.27.1

juanfont/headscalev0.27.1Nov 11, 2025by github-actions[bot]

AI Summary

A patch release fixing bugs related to node expiry persistence, OIDC authentication with multiple login URLs, and policy validation, along with cleanup of old database tables.

Key Highlights

  • Expire nodes with a custom timestamp.
  • Fix node expiry reset when tailscaled restarts.
  • Fix OIDC authentication when multiple login URLs are opened.
  • Remove old unused database tables and indices.

Full Release Notes

**Minimum supported Tailscale client version: v1.64.0**

## Changes

- Expire nodes with a custom timestamp
  [#2828](https://github.com/juanfont/headscale/pull/2828)
- Fix issue where node expiry was reset when tailscaled restarts
  [#2875](https://github.com/juanfont/headscale/pull/2875)
- Fix OIDC authentication when multiple login URLs are opened
  [#2861](https://github.com/juanfont/headscale/pull/2861)
- Fix node re-registration failing with expired auth keys
  [#2859](https://github.com/juanfont/headscale/pull/2859)
- Remove old unused database tables and indices
  [#2844](https://github.com/juanfont/headscale/pull/2844)
  [#2872](https://github.com/juanfont/headscale/pull/2872)
- Ignore litestream tables during database validation
  [#2843](https://github.com/juanfont/headscale/pull/2843)
- Fix exit node visibility to respect ACL rules
  [#2855](https://github.com/juanfont/headscale/pull/2855)
- Fix SSH policy becoming empty when unknown user is referenced
  [#2874](https://github.com/juanfont/headscale/pull/2874)
- Fix policy validation when using bypass-grpc mode
  [#2854](https://github.com/juanfont/headscale/pull/2854)
- Fix autogroup:self interaction with other ACL rules
  [#2842](https://github.com/juanfont/headscale/pull/2842)
- Fix flaky DERP map shuffle test
  [#2848](https://github.com/juanfont/headscale/pull/2848)
- Use current stable base images for Debian and Alpine containers
  [#2827](https://github.com/juanfont/headscale/pull/2827)

## Upgrade

Please follow the steps outlined in the [upgrade guide](https://headscale.net/stable/setup/upgrade/) to update your existing Headscale installation.

**It's best to update from one stable version to the next** (e.g., 0.24.0 → 0.25.1 → 0.26.1) in case you are multiple releases behind. You should always pick the latest available patch release.

Be sure to check the changelog above for version-specific upgrade instructions and breaking changes.

### Backup Your Database

**Always backup your database before upgrading.** Here's how to backup a SQLite database:

```bash
# Stop headscale
systemctl stop headscale

# Backup sqlite database
cp /var/lib/headscale/db.sqlite /var/lib/headscale/db.sqlite.backup

# Backup sqlite WAL/SHM files (if they exist)
cp /var/lib/headscale/db.sqlite-wal /var/lib/headscale/db.sqlite-wal.backup
cp /var/lib/headscale/db.sqlite-shm /var/lib/headscale/db.sqlite-shm.backup

# Start headscale (migration will run automatically)
systemctl start headscale
```

## Changelog
* abed5346289cf6984363f495d8c073868522796d Document how to restrict access to exit nodes per user/group
* d23fa26395ce64cf41aa0c47f38060c4fec03942 Fix flaky TestShuffleDERPMapDeterministic by ensuring deterministic map iteration (#2848)
* 0a43aab8f5c876935f84ab9725f0e8b47dffe809 Use Debian 12 as minimum version for the deb package
* 4bd614a559ea52bb7c77983b61247d23299237df Use current stable base images for Debian and Alpine
* 785168a7b862c6b41c61cc61d6220395eb4fe6a2 changelog: prepare for 0.27.1
* 19a33394f6e0924e2fb63d2d68ad38d5c61b6630 changelog: set 0.27 date (#2823)
* af2de35b6caebd4665f2fcc74a0f3fe1b1b094fe chore: fix autogroup:self with other acl rules (#2842)
* 02c7c1a0e7eb09de9af74fc39098a034ef3d77a0 cli: only validate bypass-grpc set policy (#2854)
* 5a2ee0c391eef946a2fa8afa9d09a913ea490cf5 db: add comment about removing migrations
* 28faf8cd712657394e889bc02255af8ee8000230 db: add defensive removal of old indicies
* 456a5d5cceea654b8c7c9b4a5db2336b62de8bec db: ignore _litestream tables when validating (#2843)
* ddbd3e14ba6fb26468a7ae4925551b09fda0eda5 db: remove all old, unused tables (#2844)
* f9bb88ad24d95c2dc35fae6e433e1e8eb8faa926 expire nodes with a custom timestamp (#2828)
* 5cd15c36568acc562ca6639176b38969c64308a7 fix: make state cookies valid when client uses multiple login URLs
* 3bd4ecd9cd8ae0e349e3e3d728a9e066642931c1 fix: preserve node expiry when tailscaled restarts
* 3455d1cb59d10c86150182c13fb203a68f68125a hscontrol/db: fix RenameUser to use Updates()
* 4a8dc2d445fefe745bc5564cf1a751b4b38d2e04 hscontrol/state,db: preserve node expiry on MapRequest updates
* 4728a2ba9ea664205d07a84584a86aef8caf5a1a hscontrol/state: allow expired auth keys for node re-registration
* ddd31ba774a78eaae845c52eae0260692d8e31c4 hscontrol: use Updates() instead of Save() for partial updates
* 773a46a9688b8c7117f8e59e9dee9d4cf915754b integration: add test to replicate #2862
* 84fe3de251eb05302832b038740e08efebd09163 integration: reduce TestAutoApproveMultiNetwork matrix to 3 tests (#2815)
* d9c3eaf8c8208a408be67695f48798b195b2109a matcher: Add func for comparing Dests and TheInternet
* f658a8eacd4d86edc65424b50635afed46ca4b2a mkdocs: 0.27.1
* c649c89e00851e39b102cc3d6fd8816618d86565 policy: Reproduce exit node visibility issues
* 21e3f2598de6d0fc4d79230ca1e0e1f9e2d6a2b2 policy: fix issue where non existent user results in empty ssh pol
* a28d9bed6d42c486201949d6eee140ab9af876d5 policy: reproduce 2863 in test
* d7a43a7cf11d8bfe72b3fcf38ebf974e2a040c4d state: use AllApprovedRoutes instead of SubnetRoutes
* 2024219bd10adbb5c0d29f900ed0961ace8cc15c types: Distinguish subnet and exit node access
* bd9cf42b96dd11c9483cadc3018b23a1adf671bf types: NodeView CanAccess uses internal
* 1c0bb0338d20d3c91ad83685cb4530fd084d0a03 types: split SubnetRoutes and ExitRoutes