Sonarr/Sonarr · error · IndexerException

Indexer API call returned an error [{0}]

Error message

Indexer API call returned an error [{0}]

What it means

Thrown by the BroadcastheNet parser when the deserialized JSON-RPC response envelope contains a non-null Error property or a null Result property. Per JSON-RPC 2.0 spec, a non-null error field means the server rejected the request (authentication failure, invalid parameters, malformed method call). Null result without error indicates a protocol-level violation from the BTN API.

Source

Thrown at src/NzbDrone.Core/Indexers/BroadcastheNet/BroadcastheNetParser.cs:57

            {
                throw new IndexerException(indexerResponse, "Indexer responded with html content. Site is likely blocked or unavailable.");
            }

            if (indexerResponse.Content.ContainsIgnoreCase("Call Limit Exceeded"))
            {
                throw new RequestLimitReachedException("Cannot do more than 150 API requests per hour.");
            }

            if (indexerResponse.Content == "Query execution was interrupted")
            {
                throw new IndexerException(indexerResponse, "Indexer API returned an internal server error");
            }

            var jsonResponse = new HttpResponse<JsonRpcResponse<BroadcastheNetTorrents>>(indexerHttpResponse).Resource;

            if (jsonResponse.Error != null || jsonResponse.Result == null)
            {
                throw new IndexerException(indexerResponse, "Indexer API call returned an error [{0}]", jsonResponse.Error);
            }

            if (jsonResponse.Result.Results == 0 || jsonResponse.Result.Torrents?.Values == null)
            {
                return results;
            }

            var protocol = indexerResponse.HttpRequest.Url.Scheme + ":";

            foreach (var torrent in jsonResponse.Result.Torrents.Values)
            {
                var torrentInfo = new TorrentInfo
                {
                    Guid = $"BTN-{torrent.TorrentID}",
                    InfoUrl = $"{protocol}//broadcasthe.net/torrents.php?id={torrent.GroupID}&torrentid={torrent.TorrentID}",
                    DownloadUrl = RegexProtocol.Replace(torrent.DownloadURL, protocol),
                    Title = CleanReleaseName(torrent.ReleaseName),
                    InfoHash = torrent.InfoHash,

View on GitHub (pinned to da2284d7ea)

Solutions

  1. Inspect the interpolated error message in the exception — jsonResponse.Error contains BTN's explanation (e.g. 'Invalid API Key', 'Bad parameters').
  2. If the error mentions authentication, verify and re-enter the BTN API key in the indexer settings.
  3. If parameters are rejected, check that the search criteria (tvdbid, season, episode) are valid numbers and not empty.
  4. If the error is intermittent, it may be BTN-side throttling returning an error object rather than the text-based throttle — reduce request frequency.
  5. Check BTN API changelog or community forums if the error appeared after a BTN update.

Example fix

// The error details are in jsonResponse.Error — log them for diagnosis
if (jsonResponse.Error != null || jsonResponse.Result == null)
{
    // before: error detail is interpolated but easily lost
    throw new IndexerException(indexerResponse,
        "Indexer API call returned an error [{0}]", jsonResponse.Error);

    // after: distinguish auth errors from generic errors so the caller
    // can apply the right backoff strategy
    // if (jsonResponse.Error.Code == 401 || jsonResponse.Error.Message.ContainsIgnoreCase("api key"))
    //     throw new ApiKeyException(jsonResponse.Error.Message);
    // throw new IndexerException(indexerResponse,
    //     "BTN API error [{0}]: {1}", jsonResponse.Error.Code, jsonResponse.Error.Message);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate BTN API key is configured before making requests
if (settings.ApiKey.IsNullOrWhiteSpace())
{
    throw new ApiKeyException("BTN API key is not configured");
}

Try / catch

// IndexerException carries the BTN JSON-RPC error detail in its message.
// Catch it and inspect the message for auth errors vs. transient errors:
try
{
    return await FetchPage(request, parser);
}
catch (IndexerException ex)
{
    if (ex.Message.ContainsIgnoreCase("api key") || ex.Message.ContainsIgnoreCase("unauthorized"))
    {
        // Auth failure — surface to user for credential fix
        throw new ApiKeyException(ex.Message);
    }
    // Transient or parameter error — log and continue
    _logger.Warn(ex, "BTN API error, will retry on next cycle");
    return Array.Empty<ReleaseInfo>();
}

Prevention

When it happens

Trigger: The BTN API returns a valid JSON-RPC response with an error object — e.g. invalid API key, insufficient privileges, unknown method, parameter validation failure, or an internal BTN-side processing error that JSON-RPC reports gracefully. Also triggered if the response deserializes successfully but the Result member is unexpectedly null.

Common situations: API key revoked or expired on the BTN side; the BTN API changed its method signatures in a version update; calling a BTN method the account lacks permission for; malformed search parameters that BTN rejects; BTN API behind a proxy that strips the result payload.

Related errors


AI-assisted analysis of Sonarr/Sonarr@da2284d7ea (2026-08-13). Data as JSON: /api/errors/f441391269be5bb2. Report an issue: GitHub.