Kareadita/Kavita · error · KavitaException

errors.font-manual-upload

Error message

errors.font-manual-upload

What it means

Thrown by FontService.CreateFontFromFileAsync when the uploaded font file does not exist at the given temp path. The check directoryService.FileSystem.File.Exists(path) returns false, meaning either the upload did not complete, the temp file was cleaned up, or the path is wrong. It is a KavitaException (UI-facing, not Sentry-reported).

Source

Thrown at Kavita.Services/FontService.cs:92

    public required int nanos { get; init; }
}

public class FontService(IDirectoryService directoryService, IUnitOfWork unitOfWork, ILogger<FontService> logger,
    IUrlValidationService urlValidationService)
    : IFontService
{
    private const string SupportedFontUrlPrefix = "https://fonts.google.com/";
    private const string DownloadFontUrlPrefix = "https://fonts.google.com/download/list?family=";
    private const string GoogleFontsInvalidJsonPrefix = ")]}'";


    public async Task<EpubFont> CreateFontFromFileAsync(string path, CancellationToken ct = default)
    {
        // Validate that font was uploaded
        if (!directoryService.FileSystem.File.Exists(path))
        {
            logger.LogInformation("Unable to create font from manual upload as font not in temp");
            throw new KavitaException("errors.font-manual-upload");
        }

        // Extract filename and then parse font object from the filename
        var fileName = directoryService.FileSystem.FileInfo.New(path).Name;
        var font = Parser.ParseEpubFontFromFilename(fileName);

        var dbFont = await unitOfWork.EpubFontRepository.GetFontByNameAsync(font.Name, ct);

        // Check if font name is already present in database
        // If it is, return the one that is already in the database.
        if (dbFont != null)
        {
            return dbFont;
        }

        // Copy file from temp directory to EpubFontDirectory
        directoryService.CopyFileToDirectory(path, directoryService.EpubFontDirectory);

View on GitHub (pinned to 9c3e540000)

Solutions

  1. Re-upload the font file and ensure the upload completes without error
  2. Check the reverse proxy and Kavita's max upload size limits are large enough for the font file
  3. Verify the temp directory has sufficient disk space and write permissions
  4. Inspect server logs for upload errors or temp file cleanup messages preceding this error

Example fix

// No code fix needed — this is an operational/upload issue.
// Ensure the upload pipeline delivers the file to temp before this method runs.
// Check: ls -la /temp/font/path/ to confirm the file arrived.
Defensive patterns

Strategy: validation

Validate before calling

// Verify the uploaded font file exists in temp before processing:
// if (!directoryService.FileSystem.File.Exists(path)) {
//     return BadRequest("Font upload failed — no file received. Please try uploading again.");
// }

Try / catch

// try {
//     var font = await fontService.CreateFontFromFileAsync(path, ct);
//     return Ok(font);
// } catch (KavitaException ex) when (ex.Message == "errors.font-manual-upload") {
//     return BadRequest(new { error = "Font file was not received. The upload may have failed. Please retry." });
// }

Prevention

When it happens

Trigger: Font upload was interrupted or failed before the file reached the temp directory; the temp cleanup task ran between upload completion and this method call; the path passed does not match where the upload middleware stored the file; file size exceeded upload limits and was silently dropped.

Common situations: Upload timeout or network interruption during font file upload; reverse proxy (nginx, Cloudflare) with a body size limit smaller than the font file; temp directory configured on a volume with insufficient space; anti-virus or security software quarantining font files.

Related errors


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