Kareadita/Kavita · warning · KavitaException

font-url-not-allowed

Error message

font-url-not-allowed

What it means

Thrown by FontService.CreateFontsFromUrl when the provided URL does not start with the required prefix 'https://fonts.google.com/'. This is a security and validation guard — only Google Fonts URLs are accepted for automatic font download. The check is a simple StartsWith comparison with the hardcoded constant.

Source

Thrown at Kavita.Services/FontService.cs:166

        await ResetFamilyReferences(family);

        foreach (var file in files)
        {
            MoveFontFileToTemp(file);
            unitOfWork.EpubFontRepository.Remove(file);
        }

        await unitOfWork.CommitAsync(ct);

        return new FontDeleteResultDto {Deleted = true, InUse = inUse};
    }

    public async Task<EpubFont[]> CreateFontsFromUrl(string url, CancellationToken ct = default)
    {
        if (!url.StartsWith(SupportedFontUrlPrefix))
        {
            throw new KavitaException("font-url-not-allowed");
        }

        // Extract Font name from url
        var fontFamily = url.Split(SupportedFontUrlPrefix)[1].Split("?")[0].Split("/").Last();
        logger.LogInformation("Preparing to download {FontName} font", fontFamily.Sanitize());

        var metaData = await GetGoogleFontsMetadataAsync(fontFamily);
        if (metaData == null)
        {
            logger.LogError("Unable to find metadata for {FontName}", fontFamily.Sanitize());
            throw new KavitaException("errors.font-not-found");
        }

        // Choose the variable font if available
        // Otherwise take the full list.
        // This should be fine since Google Fonts seems to
        // only prepend filenames with 'static/' for font
        // families that have variable fonts since the

View on GitHub (pinned to 9c3e540000)

Solutions

  1. Use a valid Google Fonts URL in the format: https://fonts.google.com/<family-name>
  2. Ensure the URL starts with exactly 'https://fonts.google.com/' (note the trailing slash)
  3. For non-Google fonts, use the manual upload feature (CreateFontFromFileAsync) instead of the URL method
  4. Trim leading/trailing whitespace from the URL before submission

Example fix

// Correct URL format:
// https://fonts.google.com/css2?family=Roboto
// or simply:
// https://fonts.google.com/Roboto

// Client-side validation:
// if (!url.startsWith('https://fonts.google.com/')) {
//   toast.error('Only Google Fonts URLs (https://fonts.google.com/...) are supported');
//   return;
// }
Defensive patterns

Strategy: validation

Validate before calling

// Validate URL prefix before calling CreateFontsFromUrl:
// const prefix = 'https://fonts.google.com/';
// if (!url || !url.startsWith(prefix)) {
//     return BadRequest($"Only Google Fonts URLs starting with '{prefix}' are supported.");
// }
// url = url.trim(); // sanitize whitespace

Try / catch

// try {
//     var fonts = await fontService.CreateFontsFromUrl(url, ct);
//     return Ok(fonts);
// } catch (KavitaException ex) when (ex.Message == "font-url-not-allowed") {
//     return BadRequest(new { error = "Only Google Fonts URLs (https://fonts.google.com/...) are allowed." });
// }

Prevention

When it happens

Trigger: User pastes a direct font file URL (e.g., .woff2 link) instead of a Google Fonts family page; user uses http:// instead of https://; user submits a URL from another font provider (Font Squirrel, Adobe Fonts); URL has leading whitespace or an unexpected scheme.

Common situations: User misunderstands the required URL format; user attempts to use a self-hosted font URL; URL is copied from a browser that stripped the protocol or added a trailing path; typo in the URL scheme.

Related errors


AI-assisted analysis of Kareadita/Kavita@9c3e540000 (2026-08-13). Data as JSON: /api/errors/46c9042a46a4d972. Report an issue: GitHub.