tailscale/tailscale · error

disallowed target host %q in redirect URL %q

Error message

disallowed target host %q in redirect URL %q

What it means

Raised when a parsed redirect URL is well-formed but its hostname is not in allowedHosts (and it is not a same-host self redirect). This is the open-redirect protection: the redirect would send users to a host the application has not explicitly approved.

Source

Thrown at tsweb/tsweb.go:1013

	}

	url, err := url.Parse(urlStr)
	if err != nil {
		return nil, fmt.Errorf("invalid redirect URL %q: %w", urlStr, err)
	}
	// Redirects to self are always allowed. A self redirect must
	// start with url.Path, all prior URL sections must be empty.
	isSelfRedirect := url.Scheme == "" && url.Opaque == "" && url.User == nil && url.Host == ""
	if isSelfRedirect {
		return url, nil
	}
	for _, allowed := range allowedHosts {
		if strings.EqualFold(allowed, url.Hostname()) {
			return url, nil
		}
	}

	return nil, fmt.Errorf("disallowed target host %q in redirect URL %q", url.Hostname(), urlStr)
}

// hasSafeRedirectPrefix reports whether url starts with a slash, or
// one of the case-insensitive strings "http://" or "https://".
func hasSafeRedirectPrefix(url string) bool {
	if len(url) >= 1 && url[0] == '/' {
		return true
	}
	const http = "http://"
	if len(url) >= len(http) && strings.EqualFold(url[:len(http)], http) {
		return true
	}
	const https = "https://"
	if len(url) >= len(https) && strings.EqualFold(url[:len(https)], https) {
		return true
	}
	return false
}

View on GitHub (pinned to 6e0912f979)

Solutions

  1. Add the intended target host to the allowedHosts list if the redirect is legitimate
  2. Otherwise treat as an open-redirect attempt and reject the request
  3. Prefer relative/self redirects to avoid expanding the allow-list
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at tsweb/tsweb.go:1013 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of tailscale/tailscale@6e0912f979 (2026-08-18). Data as JSON: /api/errors/79eaa238a28fe450. Report an issue: GitHub.