Kareadita/Kavita · error · KavitaException

Invalid Base64 string

Error message

Invalid Base64 string

What it means

Thrown by ImageService.CreateThumbnailFromBase64 when Convert.FromBase64String(encodedImage) raises a FormatException — i.e. the input is not a valid Base64 group of 4-char blocks. The FormatException is wrapped in a KavitaException so the UI sees a friendly message instead of a raw framework error. Any non-FormatException (e.g. bad image bytes) is swallowed and logged, returning an empty string instead.

Source

Thrown at Kavita.Services/ImageService.cs:418

    /// <inheritdoc />
    public string CreateThumbnailFromBase64(string encodedImage, string fileName, EncodeFormat encodeFormat,
        int thumbnailWidth = ThumbnailWidth, int thumbnailHeight = ThumbnailHeight, string? targetDirectory = null)
    {
        // TODO: This code has no concept of cropping nor Thumbnail Size
        try
        {
            targetDirectory ??= directoryService.CoverImageDirectory;
            using var thumbnail = Image.ThumbnailBuffer(Convert.FromBase64String(encodedImage), thumbnailWidth, height: thumbnailHeight);

            fileName += encodeFormat.GetExtension();
            thumbnail.WriteToFile(directoryService.FileSystem.Path.Join(targetDirectory, fileName));

            return fileName;
        }
        catch (FormatException e)
        {
            throw new KavitaException("Invalid Base64 string", e);
        }
        catch (Exception e)
        {
            logger.LogError(e, "Error creating thumbnail from url");
        }

        return string.Empty;
    }

    /// <inheritdoc />
    public string CreateThumbnailFromFile(string sourceFile, string fileName, EncodeFormat encodeFormat,
        int thumbnailWidth = 320, int thumbnailHeight = 455, string? targetDirectory = null)
    {
        try
        {
            targetDirectory ??= directoryService.CoverImageDirectory;
            using var thumbnail = Image.Thumbnail(sourceFile, thumbnailWidth, thumbnailHeight);

View on GitHub (pinned to 9c3e540000)

Solutions

  1. Strip any data-URI prefix before calling CreateThumbnailFromBase64 (split on ',' and use the second part).
  2. Validate the string with a regex like ^[A-Za-z0-9+/]+={0,2}$ and length % 4 == 0 before posting.
  3. If your source is Base64URL, convert it to standard Base64 (replace - with +, _ with /) and re-pad to a multiple of 4.
  4. Re-encode the original bytes with Convert.ToBase64String on the server or FileReader.readAsDataURL on the client to guarantee format.

Example fix

// before
var name = imageService.CreateThumbnailFromBase64(rawDataUri, "cover", format);

// after
var b64 = rawDataUri.Contains(',') ? rawDataUri.Split(',')[1] : rawDataUri;
b64 = b64.Trim().Replace('-', '+').Replace('_', '/');
b64 = b64.PadRight((b64.Length + 3) / 4 * 4, '=');
var name = imageService.CreateThumbnailFromBase64(b64, "cover", format);
Defensive patterns

Strategy: validation

Validate before calling

static readonly Regex B64 = new(@"^[A-Za-z0-9+/]+={0,2}$", RegexOptions.Compiled);

bool TryNormalizeBase64(string raw, out string b64)
{
    b64 = raw.Contains(',') ? raw.Split(',', 2)[1] : raw;
    b64 = b64.Trim().Replace('-', '+').Replace('_', '/');
    b64 = b64.PadRight((b64.Length + 3) / 4 * 4, '=');
    return B64.IsMatch(b64) && b64.Length % 4 == 0;
}

if (!TryNormalizeBase64(payload, out var clean))
    return BadRequest("Invalid Base64 image.");

Type guard

bool IsBase64Image(string raw)
{
    var body = raw.Contains(',') ? raw.Split(',', 2)[1] : raw;
    body = body.Trim().Replace('-', '+').Replace('_', '/');
    body = body.PadRight((body.Length + 3) / 4 * 4, '=');
    try { Convert.FromBase64String(body); return true; }
    catch { return false; }
}

Try / catch

try { name = imageService.CreateThumbnailFromBase64(clean, fn, fmt); }
catch (KavitaException ex) when (ex.Message == "Invalid Base64 string")
{ /* reject upload with a clear 'image encoding invalid' message */ }

Prevention

When it happens

Trigger: Posting a cover/thumbnail upload whose payload is not padded/encoded correctly: missing Base64 padding ('='), contains characters outside [A-Za-z0-9+/=], length not a multiple of 4, or the data-URL prefix 'data:image/png;base64,' was left attached to the string passed to Convert.FromBase64String.

Common situations: Frontend sends the raw data-URI scheme prefix with the Base64 body; a copy-paste truncates the trailing padding; an image was encoded as Base64URL (- _ instead of + /) rather than standard Base64; whitespace or a newline inserted mid-string.

Related errors


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