SubtitleEdit/subtitleedit · error · Exception

"Perhaps billing is not enabled (or API key is invalid)?"

Error message

"Perhaps billing is not enabled (or API key is invalid)?"

What it means

Thrown by GoogleTranslateV2 when the POST returns HTTP 403 Forbidden. Google returns 403 when billing is not enabled, the API is not enabled for the project, or the API key is invalid/restricted. Note the message string contains literal escaped quotes (\"...\"), which is a copy-paste artifact in the source.

Source

Thrown at src/libuilogic/AutoTranslate/GoogleTranslateV2.cs:80

                    try
                    {
                        Error = await result.Content.ReadAsStringAsync(cancellationToken);
                        SeLogger.Error($"Error in {StaticName}.Translate: " + Error);
                    }
                    catch
                    {

                        // ignore
                    }
                }

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

                if (!result.IsSuccessStatusCode)
                {
                    throw new Exception($"An error occurred calling GT translate - status code: {result.StatusCode}");
                }

                content = await result.Content.ReadAsStringAsync(cancellationToken);
            }
            catch (WebException webException)
            {
                var message = string.Empty;
                if (webException.Message.Contains("(400) Bad Request"))
                {
                    message = "API key invalid (or perhaps API/billing is not enabled)?";
                }
                else if (webException.Message.Contains("(403) Forbidden."))
                {

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Enable billing on the GCP project (Cloud Translation requires an active billing account).
  2. Enable the Cloud Translation API in APIs & Services.
  3. Check the API key restrictions in the console and loosen them if needed.
  4. Verify daily quota has not been exhausted in the GCP quotas page.

Example fix

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

// after - remove the stray escaped quotes and include Google's error body
if ((int)result.StatusCode == 403)
{
    throw new Exception($"GoogleTranslateV2 returned 403 (billing not enabled, API not enabled, or key invalid/restricted): {Error}");
}
Defensive patterns

Strategy: validation

Validate before calling

// Check that the GCP project is likely usable: key present + a usage probe
var key = Configuration.Settings.Tools.GoogleApiV2Key;
if (string.IsNullOrWhiteSpace(key))
    throw new InvalidOperationException("Google V2 API key missing.");
// Quick probe: list languages (cheap) to confirm billing/API/key state
using var c = new HttpClient();
var resp = await c.GetAsync($"https://translation.googleapis.com/language/translate/v2/languages?key={key}");
if ((int)resp.StatusCode == 403)
    throw new InvalidOperationException("Google returned 403 on a probe - enable billing and the Translation API, or fix key restrictions.");

Try / catch

try
{
    return await googleV2.Translate(text, src, tgt, token);
}
catch (Exception ex) when (ex.Message.Contains("billing is not enabled"))
{
    throw new InvalidOperationException("Google returned 403 - billing or the Translation API is not enabled, or the key is restricted.", ex);
}

Prevention

When it happens

Trigger: Translate() posts with the key; result.StatusCode is 403. The Error field was already populated and logged at lines 62-66 if reading the body succeeded.

Common situations: Billing disabled on the GCP project; Translation API not enabled; API key restricted by IP/referrer that does not match the caller; key deleted or disabled in the console; daily quota exceeded can also surface as 403.

Related errors


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