SubtitleEdit/subtitleedit · error · OcrException

API key invalid (or perhaps billing/API is not enabled)?

Error message

API key invalid (or perhaps billing/API is not enabled)?

What it means

Thrown by GoogleVisionOcr.Ocr when the Cloud Vision API responds with HTTP 400. 400 from the Vision endpoint means the request was rejected — most commonly an invalid API key passed as ?key=. The message hints billing/API enablement as a secondary cause.

Source

Thrown at src/ui/Features/Ocr/Engines/GoogleVisionOcr.cs:190

        requestBody.requests.Add(request);

        // Convert to JSON string
        string requestBodyString;
        using (var memoryStream = new MemoryStream())
        {
            new DataContractJsonSerializer(typeof(RequestBody)).WriteObject(memoryStream, requestBody);
            requestBodyString = Encoding.Default.GetString(memoryStream.ToArray());
        }

        // Do request
        var uri = $"?key={apiKey}";
        string content;
        try
        {
            var result = await _httpClient.PostAsync(uri, new StringContent(requestBodyString), cancellationToken);
            if ((int)result.StatusCode == 400)
            {
                throw new OcrException("API key invalid (or perhaps billing/API is not enabled)?");
            }

            if ((int)result.StatusCode == 403)
            {
                throw new OcrException("\"Perhaps billing is not enabled (or API not enabled or API key is invalid)?\"");
            }

            if (!result.IsSuccessStatusCode)
            {
                throw new OcrException($"An error occurred calling Cloud Vision API - status code: {result.StatusCode}");
            }

            content = await result.Content.ReadAsStringAsync(cancellationToken);
        }
        catch (HttpRequestException httpException)
        {
            throw new OcrException("Error calling Cloud Vision API: " + httpException.Message, httpException);
        }

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Regenerate the API key in the Google Cloud Console and paste it exactly (no spaces/quotes).
  2. Confirm the key belongs to the project where the Vision API is enabled.
  3. Verify the key is authorised for the Cloud Vision API.
  4. If using a restricted key, add the Vision API referrer/IP restriction that matches the call site.

Example fix

// before: stale/wrong key
var ocr = new GoogleVisionOcr(httpClient);
await ocr.Ocr(bmp, "AIzaSyOLDKEY", "en", ct);
// after: freshly minted key from the right project
await ocr.Ocr(bmp, Environment.GetEnvironmentVariable("GCV_API_KEY"), "en", ct);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrWhiteSpace(apiKey) || apiKey.Length < 30)
    throw new OcrException("Google Vision API key looks invalid/empty.");

Type guard

static bool LooksLikeValidGcvKey(string k) => !string.IsNullOrWhiteSpace(k) && k.StartsWith("AIza", StringComparison.Ordinal);

Try / catch

null

Prevention

When it happens

Trigger: await _httpClient.PostAsync(uri, ...) returns a result with (int)result.StatusCode == 400.

Common situations: Wrong/typo API key; key from a different Google project; key revoked; trailing whitespace in the key; calling the wrong endpoint that returns 400 for the payload.

Related errors


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