SubtitleEdit/subtitleedit · error · OcrException
"Perhaps billing is not enabled (or API not enabled or API k
Error message
"Perhaps billing is not enabled (or API not enabled or API key is invalid)?"
What it means
Thrown by GoogleVisionOcr.Ocr on HTTP 403 from Cloud Vision. 403 means authenticated but forbidden — billing disabled, the Vision API not enabled on the project, or the key lacks permission. Note the message text itself contains literal escaped quote characters (\"...\"), which is a cosmetic bug in the source string, but the exception type (OcrException) and HTTP code are the meaningful signal.
Source
Thrown at src/ui/Features/Ocr/Engines/GoogleVisionOcr.cs:195
{
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);
}
return string.Join(Environment.NewLine, JsonToStringList(language, content));
}
public static List<string> JsonToStringList(string language, string content)View on GitHub (pinned to 17a9f07487)
Solutions
- Link a billing account to the Google Cloud project (Vision requires billing even for the free tier).
- Enable the Cloud Vision API in the same project that issued the key.
- Remove key restrictions that block Vision, or create an unrestricted key for testing.
- Check the API console for quota/abuse blocks.
Example fix
// console steps // 1. APIs & Services -> Library -> enable "Cloud Vision API" // 2. Billing -> link a billing account // 3. APIs & Services -> Credentials -> recreate the key
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: warn if billing not set. The API itself must confirm at runtime.
if (string.IsNullOrWhiteSpace(apiKey)) throw new OcrException("Missing Google Vision API key."); Type guard
null
Try / catch
try { return await ocr.Ocr(bmp, key, lang, ct); }
catch (OcrException ex) when (ex.Message.Contains("billing")) {
logger.Error("Enable billing + Vision API on the Google project, then retry."); throw; } Prevention
- Enable billing and the Cloud Vision API before generating the key.
- Use the same project for the key and the API enablement.
- Keep an unrestricted test key to isolate restriction-related 403s.
When it happens
Trigger: result.StatusCode == 403 after posting to the Vision endpoint with a key Google accepted syntactically.
Common situations: Project has Cloud Vision API enabled but no billing account linked; API enabled in a different project than the key; key restricted away from Vision; quota exhausted.
Related errors
- "Perhaps billing is not enabled (or API not enabled or API k
- API key invalid (or perhaps billing/API is not enabled)?
- An error occurred calling Cloud Vision API - status code: {r
- Error calling Cloud Vision API: {httpException.Message}
- API key invalid (or perhaps billing is not enabled)?
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/954d59fef80598c2.
Report an issue: GitHub.