juanfont/headscale · error

auth request rejected

Error message

auth request rejected

What it means

Wrapped error from doLoginURLWithClient when resp.Location() fails on a 3xx response. Location() errors when the Location header exists but cannot be parsed as a URL, or (per stdlib) when there are multiple Location headers. Note the body is still returned alongside the error.

Source

Thrown at hscontrol/api/v1/auth.go:19

package apiv1

import (
	"context"
	"errors"
	"net/http"

	"github.com/danielgtaylor/huma/v2"
	"github.com/juanfont/headscale/hscontrol/types"
	"github.com/juanfont/headscale/hscontrol/util"
)

func init() {
	registrations = append(registrations, registerAuth)
}

// errAuthRejected is the verdict handed to the waiting registration flow when
// an auth session is rejected.
var errAuthRejected = errors.New("auth request rejected")

// AuthRegisterRequestBody is the v1.AuthRegisterRequest body.
type AuthRegisterRequestBody struct {
	User   string `json:"user,omitempty"`
	AuthID string `json:"authId,omitempty"`
}

// AuthApproveRequestBody is the v1.AuthApproveRequest body.
type AuthApproveRequestBody struct {
	AuthID string `json:"authId,omitempty"`
}

// AuthRejectRequestBody is the v1.AuthRejectRequest body.
type AuthRejectRequestBody struct {
	AuthID string `json:"authId,omitempty"`
}

type (

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Log the raw Location header and fix the configuration producing it (headscale server_url, OIDC issuer).
  2. If using a custom/mock OIDC provider in tests, make it emit an absolute, well-formed Location.
  3. Use the returned body in the error handler for diagnostics.
Defensive patterns

Strategy: validation

Validate before calling

if resp.StatusCode >= 300 && resp.StatusCode < 400 {
    if loc := resp.Header.Get("Location"); loc != "" {
        if _, err := url.Parse(loc); err != nil {
            return fmt.Errorf("malformed Location %q: %w", loc, err)
        }
    }
}

Prevention

When it happens

Trigger: A 3xx response whose Location header is malformed (unparseable URL) — e.g. a misconfigured OIDC issuer_url or server_url producing a broken redirect target.

Common situations: Wrong server_url / issuer base URL configuration in headscale or the OIDC provider (missing scheme, bad characters), or a test stub returning a relative/malformed Location.

Related errors


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