401 Unauthorized loop caused by cached expired basic-auth credentials in Dart HttpClient
0 reputation · 28 Mar 2023, 10:44 UTC
0 reputation · 28 Mar 2023, 10:44 UTC
Determine whether Dart's HttpClient should automatically discard cached basic-auth credentials after a server returns HTTP 401 Unauthorized due to expired or invalid credentials, thereby breaking the repeat-authentication loop.
The SDK notes that credential handling is the caller's responsibility and that the client does not clear cached credentials on a 401 response, which can cause unnecessary traffic and potential denial-of-service in long-running services.
Given that future Dart SDK versions might change this caching policy, what is the expected behavior for credential expiration, and should the API provide an automatic invalidation mechanism or remain explicit?
32775 reputation · 28 Mar 2023, 22:24 UTC
Dart's dart:io HttpClient does not discard cached basic-auth credentials after a server returns 401 Unauthorized. Credentials supplied via addCredentials or an authenticate callback are applied when the server challenges, and the client treats a 401 that follows an authenticated attempt as a server-side rejection — not as a signal to purge stored credentials. The SDK documents credential handling as the caller's responsibility, so the client will not silently decide whether the credentials are permanently invalid or transiently rejected.
This means the repeat-authentication loop is almost always a property of your own retry logic, not of an internal cache being mis-managed. If your code unconditionally re-adds the same expired credentials on every 401, the client will faithfully resend them, generating unnecessary traffic and, in long-running services, a potential denial-of-service pattern against your own backend.
Since the SDK provides no automatic invalidation mechanism, implement explicit invalidation in your application layer:
authenticate implementation checks credential freshness before responding to a challenge, rather than blindly returning the stale password.The explicit model is defensible: when to discard credentials, how many retries to allow, and how to scope invalidation by realm are policy decisions that vary by application. Embedding one policy in the SDK would be wrong for many use cases. That said, a convenience helper (for example, a failure-counting credential wrapper) could reasonably be proposed through the Dart SDK issue tracker. Note that behavior around authentication callbacks can vary across SDK releases, so confirm against the version you actually deploy and check the changelog for any credential-invalidation additions.
To confirm where your loop originates, point HttpClient at a test server that issues a 401 challenge followed by a second 401 after credentials, and log the outgoing Authorization headers. If the header is identical across cycles, the loop is in your retry path, not in HttpClient internals. Add a per-origin 401 counter to your client wrapper and confirm the loop stops once invalidation triggers. Finally, if credentials are sent over plaintext HTTP, switch to HTTPS first — cache behavior is irrelevant if the credentials are exposed on the wire.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.