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

OcrException thrown when the Cloud Vision REST call returns HTTP 403. 403 means authentication succeeded but access is forbidden — most often because billing is disabled, the Vision API is not enabled on the project, or the API key has API restrictions excluding Vision. Note the message text accidentally contains escaped quotes from the source literal.

Source

Thrown at src/libuilogic/Ocr/Service/GoogleCloudVisionApi.cs:209

            {
                new DataContractJsonSerializer(typeof(RequestBody)).WriteObject(memoryStream, requestBody);
                requestBodyString = Encoding.Default.GetString(memoryStream.ToArray());
            }

            // Do request
            var uri = $"?key={_apiKey}";
            string content;
            try
            {
                var result = _httpClient.PostAsync(uri, new StringContent(requestBodyString)).Result;
                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 = result.Content.ReadAsStringAsync().Result;
            }
            catch (WebException webException)
            {
                var message = string.Empty;
                if (webException.Message.Contains("(400) Bad Request"))
                {
                    message = "API key invalid (or perhaps billing is not enabled)?";
                }
                else if (webException.Message.Contains("(403) Forbidden."))
                {

View on GitHub (pinned to 17a9f07487)

Solutions

  1. In GCP Console, open Billing and link an active billing account to the project.
  2. Under APIs & Services, enable 'Cloud Vision API' for the project.
  3. Edit the API key restrictions to allow Cloud Vision API (or remove restrictions for testing).
  4. Check IAM/APIs & Services > Quotas for 403-driven quota caps if billing is already on.

Example fix

// before
throw new OcrException("\"Perhaps billing is not enabled (or API not enabled or API key is invalid)?\"");

// after — fix the stray quotes and keep the body for triage
throw new OcrException($"Cloud Vision API returned 403 Forbidden. Billing/API not enabled or key restricted. Body: {result.Content.ReadAsStringAsync().Result}");
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try { content = CallVision(...); }
catch (OcrException ex) when (ex.Message.Contains("billing") || ex.Message.Contains("403"))
{ SeLogger.Error(ex, "Enable billing + Cloud Vision API in GCP, then retry."); throw; }

Prevention

When it happens

Trigger: Posting to Vision with a valid-format key on a project where Cloud Vision API is disabled, billing is disabled, the key is restricted to other APIs, or per-key quotas were exceeded.

Common situations: Free-tier project where billing was never enabled; trial credits exhausted; API key restricted to 'Maps JavaScript API' only; project suspended by Google.

Related errors


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