SubtitleEdit/subtitleedit · error · Exception

Location header not found

Error message

Location header not found

What it means

Thrown by Core.FetchAsync inside the 302 handling branch when response.Headers.Location is null. The consent redirect logic needs the Location URI to follow the redirect; if Google returned a 302 without a Location header (malformed response or intermediate proxy), the handshake cannot proceed and a generic Exception is raised.

Source

Thrown at src/ui/Logic/Ocr/GoogleLens/Core.cs:175

        if (response.StatusCode == System.Net.HttpStatusCode.Found)
        {
            if (secondTry)
            {
                throw new CoreError("Lens returned a 302 status code twice", (int)response.StatusCode, response.Headers, text);
            }

            var consentHeaders = HeaderData.GenerateHeaders();
            consentHeaders["Content-Type"] = "application/x-www-form-urlencoded";
            consentHeaders["Referer"] = "https://consent.google.com/";
            consentHeaders["Origin"] = "https://consent.google.com";

            GenerateCookieHeader(consentHeaders);

            var location = response.Headers.Location;
            if (location == null)
            {
                throw new Exception("Location header not found");
            }

            var redirectLink = new Uri(location.ToString());
            var params2 = new Dictionary<string, string>
            {
                { "x", "6" },
                { "set_eom", "true" },
                { "bl", "boq_identityfrontenduiserver_20240129.02_p0" },
                { "app", "0" }
            };

            await Task.Delay(500);

            var saveConsentRequest = new HttpRequestMessage(HttpMethod.Post, "https://consent.google.com/save")
            {
                Content = new FormUrlEncodedContent(params2)
            };

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Catch this and treat the Lens call as failed, falling back to another OCR source.
  2. Inspect response.Headers (available via the CoreError path if rethrown) for alternate redirect hints.
  3. Retry the request once; transient missing headers sometimes resolve.
  4. Bypass the proxy for lens.googleapis.com / consent.google.com if possible.

Example fix

// before
var result = await core.FetchAsync(formdata, dims);

// after
try { var result = await core.FetchAsync(formdata, dims); }
catch (Exception ex) when (ex.Message == "Location header not found") { await Task.Delay(1000); return await RetryOcrAsync(); }
Defensive patterns

Strategy: try-catch

Try / catch

try { var r = await core.FetchAsync(formdata, dims); }
catch (Exception ex) when (ex.Message == "Location header not found")
{ await Task.Delay(1000); return await RetryOrFallbackAsync(); }

Prevention

When it happens

Trigger: A 302 response missing the Location header — e.g. a transparent proxy rewrote the redirect, an upstream returned a 302 with an empty body and no Location, or Google's edge returned an error page with status 302.

Common situations: Corporate proxies that strip or alter Location; a transient Google edge error; a malformed intermediate response from a CDN.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/246a8fe838e61da9. Report an issue: GitHub.