duplicati/duplicati · error · Exception
Download URL is missing from authorization response
Error message
Download URL is missing from authorization response
What it means
Thrown in B2AuthHelper.GetConfigAsync (B2AuthHelper.cs:140) when the auth response parsed successfully but the downloadUrl field is empty or whitespace. ApiAuthResponse.DownloadUrl maps to the downloadUrl JSON property and is nullable string?. The downloadUrl is used for file download operations (GetAsync). Retried up to 5 times before surfacing.
Source
Thrown at Duplicati/Library/Backend/Backblaze/B2AuthHelper.cs:140
{
response = await _httpClient.SendAsync(request, ct).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
return await ReadJsonResponseAsync<ApiAuthResponse>(response, ct).ConfigureAwait(false)
?? throw new Exception("Failed to parse authorization response");
}).ConfigureAwait(false);
if (string.IsNullOrWhiteSpace(authResponse.AccountID))
throw new Exception("Account ID is missing from authorization response");
if (string.IsNullOrWhiteSpace(authResponse.APIUrl))
throw new Exception("API URL is missing from authorization response");
if (string.IsNullOrWhiteSpace(authResponse.AuthorizationToken))
throw new Exception("Authorization token is missing from authorization response");
if (string.IsNullOrWhiteSpace(authResponse.DownloadUrl))
throw new Exception("Download URL is missing from authorization response");
authResponse.APIUrl = DropTrailingSlashes(authResponse.APIUrl);
authResponse.DownloadUrl = DropTrailingSlashes(authResponse.DownloadUrl);
_configExpires = DateTime.UtcNow + TimeSpan.FromMinutes(CACHE_EXPIRATION_MINUTES);
return _CachedAuthResponse = new AuthResponse(authResponse.AccountID, authResponse.APIUrl, authResponse.AuthorizationToken, authResponse.DownloadUrl);
}
catch (Exception ex)
{
var clientError = false;
try
{
// Only retry once on client errors
if (ex is HttpRequestException { StatusCode: not null } exception)
{
var sc = (int)exception.StatusCode;
clientError = sc is >= 400 and <= 499;
View on GitHub (pinned to 3f348be3e3)
Solutions
- Verify direct connectivity to api.backblazeb2.com without TLS interception
- Regenerate the application key and retry
- Retry after a few minutes to rule out transient B2 issues
Defensive patterns
Strategy: try-catch
Try / catch
try { var config = await b2AuthHelper.GetConfigAsync(cancelToken); }
catch (Exception ex) when (ex.Message == "Download URL is missing from authorization response")
{
logger.LogError(ex, "B2 auth response missing downloadUrl after retries");
throw;
} Prevention
- Verify direct connectivity to api.backblazeb2.com without TLS interception
- Regenerate the application key and retry authentication
- Retry after a few minutes to rule out transient B2 API issues
When it happens
Trigger: The deserialized ApiAuthResponse lacks downloadUrl. After 5 retries, the bare Exception propagates. This field is needed for constructing download URLs in GetAsync.
Common situations: Proxy stripping downloadUrl from the auth response; B2 API schema change; response truncation by intermediary.
Related errors
- Account ID is missing from authorization response
- API URL is missing from authorization response
- Authorization token is missing from authorization response
- Failed to parse authorization response
- B2MissingUserID
AI-assisted analysis of duplicati/duplicati@3f348be3e3 (2026-08-13).
Data as JSON: /api/errors/7e14989f4f958073.
Report an issue: GitHub.