Kareadita/Kavita · error · KavitaException

Bad payload from Scrobble Provider

Error message

Bad payload from Scrobble Provider

What it means

Thrown in the FlurlHttpException handler when the scrobble POST returns HTTP 500 (Internal Server Error) from the Kavita+ API. Kavita interprets a 500 from Kavita+ as the upstream scrobble provider (MAL/AniList/etc.) rejecting the payload, mapping it to BadPayLoadErrorMessage = 'Bad payload from Scrobble Provider'. It first records a ScrobbleError (Comment = UnknownSeriesErrorMessage) so the series is flagged in the UI and won't keep retrying.

Source

Thrown at Kavita.Services/Plus/ScrobblingService.cs:1674

                throw new KavitaException(RateLimitHitErrorMessage);
            }

            _logger.LogError(ex, "Scrobbling to Kavita+ API failed due to error: {ErrorMessage}", ex.Message);
            if (ex.StatusCode == 500 || ex.Message.Contains("Call failed with status code 500 (Internal Server Error)"))
            {
                if (!await _unitOfWork.ScrobbleRepository.HasErrorForSeries(evt.SeriesId))
                {
                    _unitOfWork.ScrobbleRepository.Attach(new ScrobbleError()
                    {
                        Comment = UnknownSeriesErrorMessage,
                        Details = data.SeriesName,
                        LibraryId = evt.LibraryId,
                        SeriesId = evt.SeriesId
                    });
                }
                evt.SetErrorMessage(BadPayLoadErrorMessage);
                throw new KavitaException(BadPayLoadErrorMessage);
            }
            throw;
        }
    }

    #endregion

    #region BackFill

    [DisableConcurrentExecution(60 * 60 * 60)]
    public async Task CreateEventsFromExistingHistory(List<ScrobbleProvider> scrobbleProviders, int userId, CancellationToken ct = default)
    {
        foreach (var scrobbleProvider in scrobbleProviders)
        {
            await CreateEventsFromExistingHistory(scrobbleProvider, userId, ct);
        }
    }

View on GitHub (pinned to 9c3e540000)

Solutions

  1. Open the series in the UI; the ScrobbleError flag (UnknownSeriesErrorMessage) marks it — re-match or unmatch the external provider link for that series.
  2. Verify the external provider integration is healthy (valid token, provider not down) in Settings > Scrobbling.
  3. Clear the stale external ID/mapping for the affected series and let Kavita re-match.
  4. Update Kavita to the latest version in case a payload-format bug was fixed.
Defensive patterns

Strategy: try-catch

Validate before calling

// Reject events whose external mapping is missing/invalid before posting
var hasMapping = await _unitOfWork.SeriesRepository.HasExternalMatchAsync(evt.SeriesId);
if (!hasMapping)
{
    _unitOfWork.ScrobbleRepository.Attach(new ScrobbleError { Comment = UnknownSeriesErrorMessage, SeriesId = evt.SeriesId });
    return; // skip instead of letting the API 500
}

Try / catch

try { await scrobblingService.Scrobble(evt); }
catch (KavitaException ex) when (ex.Message == "Bad payload from Scrobble Provider")
{
    _logger.LogWarning("Series {Id} rejected by upstream; flagged for re-match", evt.SeriesId);
    // ScrobbleError already attached; surface a 're-match this series' hint to the user
}

Prevention

When it happens

Trigger: The Kavita+ API forwards a provider-side failure as 500; the payload references a series/mapping the external provider cannot resolve; a malformed or stale external ID was stored for the series; the provider rate-limited with a 500-shaped response.

Common situations: A series was matched to the wrong external provider entry; the provider changed its payload schema after an upgrade; metadata for a series was edited to an invalid ID; a deleted-then-readded series kept a stale external mapping.

Related errors


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