Unclaimed project
Are you a maintainer of headscale ? Claim this project to take control of your public changelog and roadmap.
Claim this project Changelog
headscale An open source, self-hosted implementation of the Tailscale control server
tailscale tailscale-control-server tailscale-server wireguard
Last updated 6 months ago
© 2026 AnnounceHQ. All rights reserved.
Back to changelogImproved October 17, 2025
v0.27.0-beta.1 Minimum supported Tailscale client version: v1.64.0
Database integrity improvements
This release includes a significant database migration that addresses
longstanding issues with the database schema and data integrity that has
accumulated over the years. The migration introduces a schema.sql file as the
source of truth for the expected database schema to ensure new migrations that
will cause divergence does not occur again.
These issues arose from a combination of factors discovered over time: SQLite
foreign keys not being enforced for many early versions, all migrations being
run in one large function until version 0.23.0, and inconsistent use of GORM's
AutoMigrate feature. Moving forward, all new migrations will be explicit SQL
operations rather than relying on GORM AutoMigrate, and foreign keys will be
enforced throughout the migration process.
We are only improving SQLite databases with this change - PostgreSQL databases
are not affected.
Please read the PR description for more technical details about the issues and solutions.
SQLite Database Backup Example:
# 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
DERPMap update frequency
The default DERPMap update frequency has been changed from 24 hours to 3 hours.
If you set the derp.update_frequency configuration option, it is recommended
to change it to 3h to ensure that the headscale instance gets the latest
DERPMap updates when upstream is changed.
Autogroups
This release adds support for the three missing autogroups: self
(experimental), member, and tagged. Please refer to the
documentation for a detailed
explanation.
autogroup:self is marked as experimental and should be used with caution, but
we need help testing it. Experimental here means two things; first, generating
the packet filter from policies that use autogroup:self is very expensive, and
it might perform, or straight up not work on Headscale installations with a
large number of nodes. Second, the implementation might have bugs or edge cases
we are not aware of, meaning that nodes or users might gain more access than
expected. Please report bugs.
Node store (in memory database)
Under the hood, we have added a new datastructure to store nodes in memory. This
datastructure is called NodeStore and aims to reduce the reading and writing
of nodes to the database layer. We have not benchmarked it, but expect it to
improve performance for read heavy workloads. We think of it as, "worst case" we
have moved the bottle neck somewhere else, and "best case" we should see a good
improvement in compute resource usage at the expense of memory usage. We are
quite excited for this change and think it will make it easier for us to improve
the code base over time and make it more correct and efficient.
BREAKING
Remove support for 32-bit binaries
#2692
Policy: Zero or empty destination port is no longer allowed
#2606
Changes
Database schema migration improvements for SQLite
#2617
IMPORTANT: Backup your SQLite database before upgrading
Introduces safer table renaming migration strategy
Addresses longstanding database integrity issues
Add flag to directly manipulate the policy in the database
#2765
DERPmap update frequency default changed from 24h to 3h
#2741
DERPmap update mechanism has been improved with retry, and is now failing
conservatively, preserving the old map upon failure.
#2741
Add support for autogroup:member, autogroup:tagged
#2572
Fix bug where return routes were being removed by policy
#2767
Remove policy v1 code #2600
Refactor Debian/Ubuntu packaging and drop support for Ubuntu 20.04.
Changelog
0512f7c57ec0e0e721132dc4efdd371de9952fcd .github/ISSUE_TEMPLATE: add node number to environment
05996a50483d576722875be8e8c30cb9b285d8d7 .github/workflow: only run a few selected postgres tests
f6c4b338fd8cf21cf9401b3e213778a86702c4a8 .github/workflows: add generate check
5ba712041809d3416d09ccc0bcc77d2357ffd31f .github/workflows: prettier
4a8d2d9ed30d17db77b5703a0aeaef9c11e05eee .github/workflows: reduce integration retry to 3
7f8b14f6f3e0267be5a6905abff2e4495b9f5a31 .github/workflows: remove integration retry
e949859d33fc0888818088d5047673561bdf1b81 Add DERP docs
bd35fcf338d678314fc5ef674d318f441fdf6fb6 Add FAQ entry about policy migration in the database
30d12dafed210316431a57349adfdb2128078feb Add FAQ entry about the recommended upgrade path
bcd80ee7733fe7d9a8cee9a96a0857046c805697 Add debugging and troubleshooting guide
76ca7a2b5005da9c8c03f8353f73975e987b55a1 Add headscale-console
98fc0563acfd6b58b059e3b0f5e38134138ea998 Bump version in docs
33e9e7a71f8fe5925fca8597a10a9b16192ff3d7 CLAUDE: split into agents
3f72ee9de8d38e28bc4059fbf3762809e07a0c00 Clarify SIGHUP log message (#2661)
51c6367bb13c63112cb5836c98906add127638e1 Correctly document the default for dns.override_local_dns
2f3c365b68fe23dbd53110b505f8a8a70d100c0e Describe how to remove a DERP region
49b3468845576c3db0970edbb9ac2a9be78ee576 Do not ignore config-example.yml
c15aa541bb9e8d834a3e2d9c12d8edacae7d8502 Document HEADSCALE_CONFIG
b50e10a1be94898e3f237fee35e9f57eea06eda8 Document breaking change for dns.override_local_dns
30cec3aa2b422a9d8184e47a747598fbe2f9f569 Document ports in use
c04e17d82ee5925df13727a3343822a5ef85af9d Document valid log levels
cd704570be8672e16a036a88b56b45b4b82d7c80 Drop support for Ubuntu 20.04
43c9c50af4d0010a0f2cd665769bb3033f16790c Drop syslog.target and systemd-managed /var/run
be337c6a33b64687c23c227038a1d45ad86469f3 Enable derp.server.verify_clients by default
e73b2a9fb9db82ea5dd1a1a5d554a585188b6b21 Ensure that a username starts with a letter (#2635)
fa619ea9f3f73200bf17b5d5abb3ecded1aa349f Fix CHANGELOG for autogroup:member and autogroup:tagged (#2733)
086fcad7d958e1f94b172e2dd25f89ccdc3e1955 Fix Internal server error on /verify (#2735)
bad783321e8ea0c77bd00933bfd5d18ec8e05bca Fix /machine/map endpoint vulnerability (#2642)
46c59a3fff6ca23e3f2676541e76fd85aad7fbb6 Fix command in bug report template
a8f2eebf6637049756b23c9ffa8c698cf54f6b4d Fix config param name in TLS doc
e7fe645be5a6f22ca8b3b1dded79de681ac0d980 Fix invocation of golangci-lint (#2703)
Remove redundant check regarding noise config
#2658 Refactor OpenID Connect documentation
#2625 Don't crash if config file is missing
#2656 Adds /robots.txt endpoint to avoid crawlers
#2643 OIDC: Use group claim from UserInfo
#2663 OIDC: Update user with claims from UserInfo before comparing with allowed
groups, email and domain
#2663 Policy will now reject invalid fields, making it easier to spot spelling
errors #2764 Add FAQ entry on how to recover from an invalid policy in the database
#2776 EXPERIMENTAL: Add support for autogroup:self
#2789 Add healthcheck command #2659
3123d5286bbeb1d4958cec3c92d5a0969b201a9b Fix typos
4e6d42d5bd698b55e444ce50e3421057870aa177 Keycloak's group format is configurable
30a1f7e68e17f495f23e1b4670ad04ecf1ac0522 Log registrationID to simplify interactive node registration
2d680b5ebb91c72589017ee9e82b46e1cdc9afe9 Misc typos and spelling
5d8a2c25ea97e47b183dfbe96a87d73f72f89ac6 OIDC: Query userinfo endpoint before verifying user
4a941a2cb4d7da056f993205c7e9c305fc49a535 Refactor Debian/Ubuntu package
d461db3abdf2de67526ae4ae1ec72337144dcce1 Refactor OpenID Connect documentation
a2a6d2021802d2113dcd0e3fb35b228aac4c3080 Refactor to use reflect.TypeFor
8ff5baadbe210a83218cef3cd635bb2a3c361eba Refresh OIDC docs
b8044c29ddc59d9c6346337d589b73a7e5b0511e Replace magic-nix-cache-action (#2575)
a98d9bd05f9b5f02bd642d5853c75d87d708fb4a The preauthkeys commands expect a user id instead of a username
881a6b92276e6913982d562e00dc09ec9ccd4bfd The sequential prefix allocation uses a best-effort approach
3fbde7a1b6636ff802f0ceff3d1546ef8a5d0dec Update official.md
860a8a597f095f788ce7abd89b12cfd75e117794 Update tools.md
4d61da30d0e5909dd1410f3927455000e1a53738 Use an IPv4 address range suitable for documentation
c6427aa296fb6aa5037e3797271ffd4f4f3e9387 Use group id instead of group name for Entra ID
c07cc491bf050dd1784d359f84cd85e5460a63e3 add health command (#2659)
7fce5065c45dc233240bd334d12999bbd7c50488 all: remove 32 bit support (#2692)
73023c2ec398d5dea8bbf0a74532c07647c77c6d all: use immutable node view in read path
d41fb4d5407944ed2c984c76b08e76efd1d06bbe app: fix sigint hanging
8e25f7f9dd12421a805f82f09676b592a39c61b9 bunch of qol (#2748)
4668e5dd9640a2730c8eb341ec2deb6c841beea3 changelog: add entry for db
e7a28a14afc6a39b286672895a792950df04f350 changelog: prepare for 0.27.0 (#2797)
d29feaef79587092b89e8efaa2221620b5c08683 chore(derp): allow nil regions in DERPMaps
630bfd265ac76f31e0a88cb7f92d356d38e9dc3d chore(derp): prioritize loading DERP maps from URLs
022098fe4ea3151a5d72cdb8311e0eefdd95cd73 chore: make reg cache expiry tunable
081af2674b9d14f9db06528f4be896bb82752cba ci: fix golangci-lint flag for v2 compatibility (#2654)
3950f8f17112a0114cc4db528097a896da8caf67 cli: use gobuild version handling (#2770)
ea7376f522607af8ba64ad73a980994da4ab00b4 cmd/hi: add integration test runner CLI tool (#2648)
afc11e1f0c1cbdc06716f221380710d92ce75a94 cmd/hi: fixes and qol (#2649)
3326c5b7ec547ca941c178cff4f3df8057c4179a cmd/hi: lint and format
684239e015e16f5786fc5b8808ab47abc77c9c57 cmd/mapresponses: add mini tool to inspect mapresp state from integration
2b30a15a685432e3b4fac259ecfba340abbd061b cmd: add option to get and set policy directly from database (#2765)
c6736dd6d68e805a584c99049e0ad018fef6decd db: add sqlite "source of truth" schema
50ed24847b932a7a3663f7c4096fd5c6686937e3 debug: add json and improve
38be30b6d4629c5bbe5339ad3c913c3cb0f156ea derp: allow override to ip for debug
7056fbb63bd0e3d512aaee3d232967cb8bddf800 derp: fix flaky shuffle test (#2772)
b87567628a88703884d2c95c0aba7b0c2f118538 derp: increase update frequency and harden on failures (#2741)
3e3c72ea6f36cfff1f467b4e3f350886973d32bb docs(acls): Add example for allow/deny all acl policy
ded049b905555a0309eab1fce060333152050013 don't crash if config file is missing (#2656)
df69840f92dbb95a7b818ba4363772550a133d8d feat(tools): Add Go client implementation
6750414db116aa4b0241c07b2d8f52f13ba045fe feat: add autogroup:member, autogroup:tagged (#2572)
c2a58a304dbd4a71ec7626ca95ece1bef26339e6 feat: add autogroup:self (#2789)
d77874373d4a1e0e7852bb6d16d84d3640a0bff5 feat: add robots.txt
d325211617d484bd5bfda3207decf4a7ad3c1a28 feat: add verify client config for embedded DERP (#2260)
1605e2a7a9c75a7aee3c46741dd446d169a5546e fix typo in TailSQL's log
efc69740176de332278e9f2369653f5f5fe74b99 fix typo in parseCapabilityVersion, and removed unused error (#2644) (#2644)
43f90d205e074983256ef1b98048adb752e310aa fix: allow all traffic if acls field is omited from the policy
3f6657ae57a3a9bda63aac61f106350b23f83a06 fix: documentation
4927e9d590e9bb4f634a2be6bdb9bf3884f8d17c fix: improve mapresponses and profiles extraction in hi tool
c4a8c038cdd6b2968f7dc967b7ca172e73e8aea0 fix: return valid AuthUrl in followup request on expired reg id
3bad5d559098c8535a3af9e4e9d86fbf63e78ce3 flake.lock: Update (#2585)
6220e649789e3c3298da41a77148c527ff2fb496 flake.lock: Update (#2669)
1a7a2f41962f74ccee7088b6613de2097046b428 flake.lock: Update (#2699)
40b3d54c1f00850e03db49408af174853414ee57 flake.lock: Update (#2755)
d311d2e206d8b29a97b035812b38c18be86bd3c9 flake: dont override gopls
4de56c40d8c397761dae5a6d2b6607632fd0ba0e flake: goreleaser doesnt follow go nix convention (#2779)
39443184d64155c76c3cb011a76f1401f557f09b gen: new proto version
22e6094a902e1d94664646626844da83684260b0 golangci: disable varnamelen
30525cee0eb14de0d587b1b4168cbf8ee462b99e goreleaser: always do draft (#2595)
a975b6a8b1cb7061b1a01e4736f25954e14e8e04 hscontrol: remove go-grpc-middleware v1 dependency (#2653)
9b962956b5fbb6b6c1a10bdc2a6a5e68ebb02515 integration: Eventually, debug output, lint and format
044193bf34b19badf2225b0aa60be44511165778 integration: Use Eventually around external calls (#2685)
c87471136b6a7b893bb8090a53d6ee6200419ef5 integration: eventually fixups (#2799)
4893cdac7471ffd01773ec27fd7afe847c5dbd12 integration: make timestamp const
c6d7b512bd3c8059a863db214f263877487ab83a integration: replace time.Sleep with assert.EventuallyWithT (#2680)
3b16b75fe6ef48d0860e54907047a351df804bb6 integration: rework retry for waiting for node sync
9779adc0b72974241b6ae4d9d633f96b7e17f326 integration: run headscale with delve and debug symbols (#2689)
306d8e1bd4b7b196b4286d89ee6fd1d0f7a97258 integration: validate expected online status in ping
233dffc1862f4193ee5ce005489106aa01a7b9b7 lint and leftover
b6d5788231c865e3d7dfa81008349a0142fdde9d mapper: produce map before poll
a058bf3cd37a2544ee00845b7abd7137e49f6843 mapper: produce map before poll (#2628)
ed3a9c8d6d3c0f45f46c24e6b42d404fb4456a09 mapper: send change instead of full update (#2775)
ccd79ed8d4ff77c16cd10eb528c88cb1671815d2 mcp: add some standard mcp server
bd6ed80936d950a1e650af43125928fea74301f3 policy/v2: error on missing or zero port (#2606)
ee0ef396a2e91413182c2b139b0b1ffb3aee4829 policy: fix ssh usermap, fixing autogroup:nonroot (#2768)
2938d03878d44491924563e26e408d2b5d51e668 policy: reject unsupported fields (#2764)
a52f1df1806538368bd671b198fe1e975806ade5 policy: remove v1 code (#2600)
01c1f6f82a003a7aaca7a8fbd010d7218fd334c1 policy: validate error message for asterix in ssh (#2766)
c91b9fc761b5fffc1beb105f92db2ce005a77730 poll: add missing godoc (#2763)
b904276f2b59181b7aa6d2ef8814bca15d462f83 poll: use nodeview everywhere
0303b76e1fb38fc5fb49400c37716d1f1146d01e postgres uses more memory
855c48aec287f0c654ed21ff740352933e3b8a1b remove unneeded check (#2658)
fddc7117e4f31d70718c20e1b666798048163127 stability and race conditions in auth and node store (#2781)
9d236571f462e364073c5b49614d37c192616c58 state/nodestore: in memory representation of nodes
476f30ab209887d85ca3a6ac675860ff1a82bea3 state: ensure netinfo is preserved and not removed
1553f0ab53d64ce8922e0de190955eb5770657cb state: introduce state
b4f7782fd8dedb5d123ca88286f7672ab6198fd3 support force flag for nodes backfillips
4912769ab3237bf9674cf7dce880e7d6926cf80a update dependencies (#2798)
81b3e8f74397b91de98421341ce85ac4fecea98b util: harden parsing of traceroute
d2879b2b3675c6c38b1a39dd7a7b44c1679287a9 web: change node registration parameter order (#2607)
1b1c98926854dd4f95efd7d63536e4bafbfdd1ab {policy, node}: allow return paths in route reduction (#2767) Go