PaddlePaddle/PaddleOCR · critical · AuthError

Authentication failed: ${text}

Error message

Authentication failed: ${text}

What it means

AuthError is thrown when the API answers HTTP 401 or 403. The message embeds the server's explanation (extracted from the body's msg/message/errorMsg field when present, else the raw text). It means the request reached the server but the credentials were rejected or lack permission for the operation.

Source

Thrown at api_sdk/typescript/src/internal/http.ts:237

      }
      const message = e instanceof Error ? e.message : String(e);
      throw new NetworkError(`Connection failed: ${message}`);
    } finally {
      clearTimeout(timeoutID);
      signal?.removeEventListener("abort", abort);
    }

    if (resp.ok) return resp;

    let text = await resp.text();
    try {
      const payload = JSON.parse(text) as { msg?: string; message?: string; errorMsg?: string };
      text = payload.msg || payload.message || payload.errorMsg || text;
    } catch {
      // Keep raw response text.
    }
    if (resp.status === 401 || resp.status === 403) {
      throw new AuthError(`Authentication failed: ${text}`);
    } else if (resp.status === 400) {
      throw new InvalidRequestError(`Bad request: ${text}`);
    } else if (resp.status === 429) {
      throw new RateLimitError(`Rate limit exceeded: ${text}`);
    } else if (resp.status === 503 || resp.status === 504) {
      throw new ServiceUnavailableError(resp.status, `Service unavailable: ${text}`);
    } else {
      throw new APIError(resp.status, text);
    }
  }
}

function requireJobId(data: SubmitResponse): string {
  if (!data || typeof data.jobId !== "string" || data.jobId.length === 0) {
    throw new ResponseFormatError("Submit response is missing jobId.");
  }
  return data.jobId;
}

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Check the key is present and non-empty in the environment where the code actually runs (print its length/prefix, never the value)
  2. Regenerate or refresh the API key/token and update configuration
  3. Confirm the key matches the environment and has the required permissions/scopes for the endpoint you call
  4. For long-running processes, build a fresh client after key rotation instead of reusing an instance holding old credentials

Example fix

try {
  const jobId = await client.submitJson(model, payload);
} catch (e) {
  if (e instanceof AuthError) {
    // re-create client with refreshed credentials and retry once
    const fresh = createClient({ apiKey: await loadFreshToken() });
    return fresh.submitJson(model, payload);
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

function hasUsableKey(key: string | undefined): boolean {
  return typeof key === "string" && key.trim().length >= 20;
}

Type guard

function isAuthError(e: unknown): e is AuthError {
  return e instanceof AuthError;
}

Try / catch

try {
  await client.submitJson(model, payload);
} catch (e) {
  if (e instanceof AuthError) {
    // do NOT retry with the same key: refresh credentials, rebuild client, retry once
    const freshClient = createClient({ apiKey: await refreshCredentials() });
    return freshClient.submitJson(model, payload);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling any authenticated method with an expired, malformed, or revoked API key/token; using a key from one environment against another (test vs prod); a token with scopes that do not cover the requested endpoint; a key that was rotated server-side while still cached in a long-lived client instance.

Common situations: Hardcoded keys rotated by a security policy; tokens expired because the clock drifted or the session TTL passed; environment variables not set in the deployment (empty-string key); free-tier keys hitting a paid-only endpoint; copying examples with placeholder keys.

Understand the failure class

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/e24929eab8a537ac. Report an issue: GitHub.