Wei-Shaw/sub2api · error

xAI OAuth redirect missing Location

Error message

xAI OAuth redirect missing Location

What it means

The device flow handles redirects manually (up to 8 hops). When a 3xx response has an empty or whitespace-only Location header, there is no way to continue, so the request fails with this error. A well-behaved OAuth server always sends Location on 3xx.

Source

Thrown at backend/internal/pkg/xai/sso_device.go:289

		if err != nil {
			return 0, currentURL, nil, err
		}
		f.captureCookies(request.URL, response)
		data, readErr := io.ReadAll(io.LimitReader(response.Body, ssoMaxAuthBody+1))
		_ = response.Body.Close()
		if readErr != nil {
			return response.StatusCode, currentURL, nil, readErr
		}
		if len(data) > ssoMaxAuthBody {
			return response.StatusCode, currentURL, nil, errors.New("xAI OAuth response exceeds 2 MiB")
		}
		if response.StatusCode < 300 || response.StatusCode > 399 {
			return response.StatusCode, currentURL, data, nil
		}

		location := strings.TrimSpace(response.Header.Get("Location"))
		if location == "" {
			return response.StatusCode, currentURL, data, errors.New("xAI OAuth redirect missing Location")
		}
		base, _ := url.Parse(currentURL)
		next, err := url.Parse(location)
		if err != nil {
			return response.StatusCode, currentURL, data, err
		}
		currentURL = base.ResolveReference(next).String()
		if !safeXAIAuthURL(currentURL) {
			return response.StatusCode, currentURL, data, errors.New("xAI OAuth redirected to untrusted host")
		}
		if response.StatusCode == http.StatusSeeOther || ((response.StatusCode == http.StatusMovedPermanently || response.StatusCode == http.StatusFound) && currentMethod != http.MethodGet && currentMethod != http.MethodHead) {
			currentMethod = http.MethodGet
			currentForm = nil
		}
	}
	return 0, currentURL, nil, errors.New("xAI OAuth redirected too many times")
}

View on GitHub (pinned to 073e92d171)

Solutions

  1. Replay the request with curl -v (same cookies) to inspect the raw 3xx and its headers.
  2. Remove intermediary proxies from the path for the OAuth hosts.
  3. Retry once; transient infra faults often clear.
  4. If xAI is genuinely returning headerless 3xx, it is a server-side incident — wait or report.
Defensive patterns

Strategy: retry

Try / catch

if err != nil && strings.Contains(err.Error(), "redirect missing Location") {
    log.Printf("3xx without Location from %s; retrying once", endpoint)
    err = flow.Start(ctx)
}

Prevention

When it happens

Trigger: Any step of the flow receives 300-399 whose Location header is missing/blank: broken server-side redirect config, a proxy stripping Location, or a 304-like status used oddly.

Common situations: Reverse proxies or TLS terminators dropping the Location header; xAI misconfiguration during incidents; HTTP/1.0 intermediaries that mishandle redirects.

Related errors


AI-assisted analysis of Wei-Shaw/sub2api@073e92d171 (2026-08-15). Data as JSON: /api/errors/82279ac5a1d102ee. Report an issue: GitHub.