TechnitiumSoftware/DnsServer · error · HttpApiClientException
Already logged in. Please create a new object to use a diffe
Error message
Already logged in. Please create a new object to use a different API token.
What it means
UseApiToken sets up token-based auth and refuses to run if the client already holds a session (_loggedIn == true), because swapping the Authorization header mid-session would corrupt state. The message explicitly directs the caller to instantiate a new HttpApiClient for a different token. Fires before any HTTP traffic.
Source
Thrown at DnsServerCore.HttpApi/HttpApiClient.cs:226
{
if (!_loggedIn)
throw new HttpApiClientException("No active session exist to logout.");
Stream stream = await _httpClient.GetStreamAsync($"api/user/logout", cancellationToken);
using JsonDocument jsonDoc = await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken);
JsonElement rootElement = jsonDoc.RootElement;
CheckResponseStatus(rootElement);
_httpClient.DefaultRequestHeaders.Remove("Authorization");
_loggedIn = false;
}
public void UseApiToken(string token)
{
if (_loggedIn)
throw new HttpApiClientException("Already logged in. Please create a new object to use a different API token.");
_httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
_loggedIn = true;
}
public async Task<DashboardStats> GetDashboardStatsAsync(string actingUsername, DashboardStatsType type = DashboardStatsType.LastHour, bool utcFormat = false, string acceptLanguage = "en-US,en;q=0.5", bool dontTrimQueryTypeData = false, DateTime startDate = default, DateTime endDate = default, CancellationToken cancellationToken = default)
{
if (!_loggedIn)
throw new HttpApiClientException("No active session exists. Please login and try again.");
string path = $"api/dashboard/stats/get?actingUser={Uri.EscapeDataString(actingUsername)}&type={type}&utc={utcFormat}&dontTrimQueryTypeData={dontTrimQueryTypeData}";
if (type == DashboardStatsType.Custom)
path += $"&start={startDate:O}&end={endDate:O}";
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Get, new Uri(_serverUrl, path));
httpRequest.Headers.Add("Accept-Language", acceptLanguage);
View on GitHub (pinned to d0484b6c1e)
Solutions
- Construct a new HttpApiClient instance for each distinct API token.
- Call LogoutAsync first if you must reuse the instance (then UseApiToken).
- Prefer a factory method that hands out fresh authenticated clients per token.
Example fix
// before client.UseApiToken(tokenA); client.UseApiToken(tokenB); // throws // after var clientB = new HttpApiClient(serverUrl); clientB.UseApiToken(tokenB);
Defensive patterns
Strategy: validation
Validate before calling
if (client.IsLoggedIn)
throw new InvalidOperationException(
"Client already authenticated. Create a new HttpApiClient for a different token.");
client.UseApiToken(token); Prevention
- Instantiate one HttpApiClient per token.
- Use a factory to vend fresh authenticated clients.
- Call LogoutAsync before reusing an instance with a new token.
When it happens
Trigger: Calling UseApiToken after LoginAsync or after a prior UseApiToken on the same instance without resetting it.
Common situations: Reusing one HttpApiClient for multiple tokens/accounts; calling UseApiToken inside a loop that processes several tokens.
Related errors
- Already logged in.
- No active session exist to logout.
- No active session exists. Please login and try again.
- Invalid JSON response was received.
- Unknown status value was received: {status}
AI-assisted analysis of TechnitiumSoftware/DnsServer@d0484b6c1e (2026-08-13).
Data as JSON: /api/errors/8a600f54808a1ccb.
Report an issue: GitHub.