juanfont/headscale · info

command aborted by user

Error message

command aborted by user

What it means

HTTP 501 emitted by noiseServer.NotImplementedHandler for any route registered inside the noise mux that headscale has not implemented (the handler logs the exact path at trace level). It is a deliberate stub: the TS2021 protocol defines endpoints headscale's control server does not serve, so unimplemented paths land here instead of 404.

Source

Thrown at cmd/headscale/cli/policy.go:22

	"context"
	"errors"
	"fmt"
	"net/http"
	"os"

	clientv1 "github.com/juanfont/headscale/gen/client/v1"
	"github.com/juanfont/headscale/hscontrol/db"
	"github.com/juanfont/headscale/hscontrol/policy"
	"github.com/juanfont/headscale/hscontrol/types"
	"github.com/spf13/cobra"
	"tailscale.com/types/views"
)

const (
	bypassFlag = "bypass-server-and-access-database-directly" //nolint:gosec // not a credential
)

var errAborted = errors.New("command aborted by user")

// bypassDatabase opens the database directly, bypassing the running server.
// The caller must close the returned handle.
func bypassDatabase() (*db.HSDatabase, error) {
	cfg, err := types.LoadServerConfig()
	if err != nil {
		return nil, fmt.Errorf("loading config: %w", err)
	}

	d, err := db.NewHeadscaleDatabase(cfg)
	if err != nil {
		return nil, fmt.Errorf("opening database: %w", err)
	}

	return d, nil
}

// openBypassDB confirms the destructive bypass action and opens the database

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Confirm the requested path from the server's trace log ('not implemented handler hit', path field) and check headscale release notes/changelog whether that endpoint is supported in a newer version.
  2. If the path corresponds to a client feature, disable that feature on the client or upgrade headscale once the endpoint ships.
  3. If you are developing a client, restrict calls to documented endpoints (map, registration, ping response, etc.).
  4. Ignore it if it is a one-off probe — it is a stub response, not a fault.
Defensive patterns

Strategy: fallback

Try / catch

resp, err := client.Do(req)
if err == nil && resp.StatusCode == http.StatusNotImplemented {
    // endpoint is a deliberate stub in headscale: degrade gracefully, do not retry the same path
    log.Printf("endpoint %s not implemented by this headscale; feature unavailable", req.URL.Path)
}

Prevention

When it happens

Trigger: A tailscaled feature requesting a control-plane endpoint inside the noise tunnel that headscale never implemented (e.g. newer or optional coordination endpoints); manually probing the noise mux with crafted requests to unknown paths.

Common situations: Newer tailscale clients exercising features (e.g. future tailcfg endpoints) that headscale does not support yet; curiosity-driven scanning of /ts2021 inner routes; custom clients calling nonstandard paths.

Related errors


AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15). Data as JSON: /api/errors/adc2e423e751089e. Report an issue: GitHub.