juanfont/headscale · error

no docker context found

Error message

no docker context found

What it means

Guard error from doLoginURLWithClient when the caller passes a nil *http.Client. The function needs a real client (with the debug cookie jar) to perform the login GET, so it refuses immediately instead of panicking on hc.Do later.

Solutions

  1. Check the error from newLoginHTTPClient before using the client.
  2. Pass the client returned by newLoginHTTPClient(hostname), never a hand-built nil.

Example fix

// before
hc, _ := newLoginHTTPClient(hostname)
body, redir, err := doLoginURLWithClient(hostname, loginURL, hc, true)
// after
hc, err := newLoginHTTPClient(hostname)
if err != nil {
    return nil, nil, err
}
body, redir, err := doLoginURLWithClient(hostname, loginURL, hc, true)
Defensive patterns

Strategy: validation

Validate before calling

hc, err := newLoginHTTPClient(hostname)
if err != nil {
    return err
}
if hc == nil {
    return fmt.Errorf("%s http client unexpectedly nil", hostname)
}

Prevention

When it happens

Trigger: Calling doLoginURLWithClient (directly or via a helper) with hc == nil — e.g. the caller ignored the error from newLoginHTTPClient and passed the nil result straight through.

Common situations: Ignoring the error from newLoginHTTPClient and proceeding with the zero-value client; refactoring that dropped client construction from a call path.

Related errors


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

Appendix: source

Thrown at cmd/hi/docker.go:31

	"path/filepath"
	"strings"
	"time"

	"github.com/cenkalti/backoff/v5"
	"github.com/docker/docker/api/types/container"
	"github.com/docker/docker/api/types/image"
	"github.com/docker/docker/api/types/mount"
	"github.com/docker/docker/client"
	"github.com/docker/docker/pkg/stdcopy"
	"github.com/juanfont/headscale/integration/dockertestutil"
)

const defaultDirPerm = 0o755

var (
	ErrTestFailed              = errors.New("test failed")
	ErrUnexpectedContainerWait = errors.New("unexpected end of container wait")
	ErrNoDockerContext         = errors.New("no docker context found")
	ErrMemoryLimitViolations   = errors.New("container(s) exceeded memory limits")
)

// runTestContainer executes integration tests in a Docker container.
//
//nolint:gocyclo // complex test orchestration function
func runTestContainer(ctx context.Context, config *RunConfig) error {
	cli, err := createDockerClient(ctx)
	if err != nil {
		return fmt.Errorf("creating Docker client: %w", err)
	}
	defer cli.Close()

	runID := dockertestutil.GenerateRunID()
	containerName := "headscale-test-suite-" + runID
	logsDir := filepath.Join(config.LogsDir, runID)

	if config.Verbose {

View on GitHub (pinned to 565fd254d0)