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
- Regenerate the API key in the Google Cloud Console and paste it exactly (no spaces/quotes).
- Confirm the key belongs to the project where the Vision API is enabled.
- Verify the key is authorised for the Cloud Vision API.
- 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
- Store the key in an env var / secret manager; never hardcode.
- Smoke-test the key with a one-image curl before batch OCR.
- Confirm the key's project has the Vision API enabled.
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
- API key invalid (or perhaps billing/API is not enabled)?
- "Perhaps billing is not enabled (or API not enabled or API k
- An error occurred calling Cloud Vision API - status code: {r
- Error calling Cloud Vision API: {httpException.Message}
- {error}
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/ea256b9baa8ba3b7.
Report an issue: GitHub.