JustArchiNET/ArchiSteamFarm · error · HttpRequestException
Failed due to error: {0}
Error message
Failed due to error: {0} What it means
Inside the inventory retry loop, if the HTTP response status is a 4xx client error (response.StatusCode.IsClientErrorCode()), ASF throws an HttpRequestException carrying that status code as the inner status. Client errors are treated as non-retryable — the request itself is wrong or unauthorized.
Source
Thrown at ArchiSteamFarm/Steam/Integration/ArchiWebHandler.cs:346
await ASF.InventorySemaphore.WaitAsync().ConfigureAwait(false);
ObjectResponse<InventoryResponse>? response = null;
try {
for (byte i = 0; (i < WebBrowser.MaxTries) && (response?.Content is not { Result: EResult.OK } || !response.StatusCode.IsSuccessCode()); i++) {
if ((i > 0) && (rateLimitingDelay > 0)) {
await Task.Delay(rateLimitingDelay).ConfigureAwait(false);
}
response = await UrlGetToJsonObjectWithSession<InventoryResponse>(request, requestOptions: WebBrowser.ERequestOptions.ReturnClientErrors | WebBrowser.ERequestOptions.ReturnServerErrors | WebBrowser.ERequestOptions.AllowInvalidBodyOnErrors | WebBrowser.ERequestOptions.SteamWafWorkarounds, rateLimitingDelay: rateLimitingDelay).ConfigureAwait(false);
if (response == null) {
throw new HttpRequestException(Strings.FormatErrorObjectIsNull(nameof(response)));
}
if (response.StatusCode.IsClientErrorCode()) {
throw new HttpRequestException(Strings.FormatWarningFailedWithError(response.StatusCode), null, response.StatusCode);
}
if (response.StatusCode.IsServerErrorCode()) {
if (string.IsNullOrEmpty(response.Content?.ErrorText)) {
// This is a generic server error without a reason, try again
continue;
}
Bot.ArchiLogger.LogGenericDebug(Strings.FormatWarningFailedWithError(response.Content.ErrorText));
// Try to interpret the failure reason and see if we should try again
switch (response.Content.ErrorCode) {
case EResult.Busy:
case EResult.DuplicateRequest:
case EResult.Fail:
case EResult.RemoteCallFailed:
case EResult.ServiceUnavailable:
case EResult.Timeout:View on GitHub (pinned to fe57c4129f)
Solutions
- Refresh the bot's web session / access token and retry.
- Confirm the target inventory is public (or owned by the bot).
- Verify the constructed inventory URL is correct for the account and app/context.
- If 429, reduce request frequency and respect rate limiting.
Defensive patterns
Strategy: try-catch
Validate before calling
// Refresh session if it is likely stale before a client error surfaces. if (sessionLikelyExpired) await bot.ArchiWebHandler.RefreshSession();
Try / catch
try { await foreach (var a in webHandler.GetInventoryAsync(steamID)) { /* ... */ } }
catch (HttpRequestException ex) when (ex.StatusCode.HasValue && (int)ex.StatusCode.Value is >= 400 and <= 499) {
// 4xx client error; refresh session or correct target, do not blind-retry
} Prevention
- Keep the bot's web session/access token fresh.
- Confirm target inventories are public or owned.
- Rate-limit your own requests to avoid 429.
When it happens
Trigger: Steam community returns a 4xx (e.g. 401 unauthorized session, 403 forbidden/private inventory, 404 not found, 429 rate-limited occasionally classified here) for the inventory endpoint.
Common situations: Expired/invalid access token (401); target inventory set to private (403); wrong profile/inventory URL (404); stale session cookies; the bot account losing web privileges.
Related errors
- Failed!
- response is null!
- Failed due to error: Client.IsConnected
- Failed due to error: {0}
- response is null!
AI-assisted analysis of JustArchiNET/ArchiSteamFarm@fe57c4129f (2026-08-13).
Data as JSON: /api/errors/391cc72808be0762.
Report an issue: GitHub.