netbirdio/netbird · warning

no daemon pipe to connect to

Error message

no daemon pipe to connect to

What it means

The scheme-flow counterpart of index 6, in handleAuthenticatedToken (middleware.go:581): a form/login scheme produced a token (token != ''), validateSessionToken errored, and the error is not errValidationUnavailable — the token fails local validation (bad Ed25519 signature, malformed). Captured data gets OriginAuth and the scheme type, then 400 'invalid session token'.

Source

Thrown at client/internal/daemonaddr/pipe_windows.go:47

		// A pipe in the protected namespace could only have been created by an
		// administrator or LocalSystem, so its name is the guarantee. Any other
		// name has to be checked, because any local user can create one.
		if !IsProtectedPipePath(path) {
			if err := ipcauth.PipeServerTrusted(conn); err != nil {
				if closeErr := conn.Close(); closeErr != nil {
					log.Debugf("close untrusted pipe %s: %v", path, closeErr)
				}
				lastErr = fmt.Errorf("%s: %w", path, err)
				continue
			}
		}

		return conn, nil
	}

	if lastErr == nil {
		lastErr = errors.New("no daemon pipe to connect to")
	}
	return nil, lastErr
}

// dialPipe connects to the daemon control pipe at SECURITY_IDENTIFICATION.
// winio's plain DialPipe connects at SECURITY_ANONYMOUS, under which the daemon
// cannot read the caller's token at all. Identification lets the daemon read the
// caller's SID and groups without granting it the ability to act as the caller.
func dialPipe(ctx context.Context, path string) (net.Conn, error) {
	access := uint32(windows.GENERIC_READ | windows.GENERIC_WRITE)
	return winio.DialPipeAccessImpLevel(ctx, path, access, winio.PipeImpLevelIdentification)
}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Re-register the domain (AddDomain) so the proxy holds the current SessionPublicKey from management.
  2. Retry the login flow end-to-end to mint a token under the current keys.
  3. Compare the session public key configured on the proxy with management's active signing key.
  4. Check the underlying validateSessionToken error in proxy logs for 'malformed' vs 'signature'.
Defensive patterns

Strategy: validation

Try / catch

resp, err := client.PostForm(loginURL, creds)
if err == nil && resp.StatusCode == http.StatusBadRequest {
    // 400 'invalid session token' right after login: key skew between
    // management (signer) and proxy (verifier). Re-sync the domain's session
    // public key, then retry the whole login; the credentials are fine.
}

Prevention

When it happens

Trigger: Submitting credentials through the domain's login page whose resulting token cannot be verified: token minted with a key other than the domain's SessionPublicKey (key rotation gap between management and proxy), token corrupted in transit, or token crafted for a different domain.

Common situations: Management rotated the session signing key but the proxy still holds the old SessionPublicKey from domain registration (re-sync never happened); stale login form resubmitted after a key change; proxy restarted with an outdated domain config.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/cf2b6e1ab4b79e95. Report an issue: GitHub.