dotnet/wpf · error · WebException
WebResponseFailure
Error message
WebResponseFailure
What it means
PackWebResponse performs its real work on a background thread; consumers block in WaitForResponse, which rethrows the outcome. If the worker signaled _responseError without an accompanying exception object, WaitForResponse throws WebException(SR.WebResponseFailure); otherwise it rethrows the original exception. This pattern is hit by GetResponseStream, InnerResponse, Headers, ResponseUri, IsFromCache, and ContentType.
Solutions
- Inspect and fix the underlying cause (check inner _responseException / inner WebException status — DNS, 404, TLS, etc.).
- Retry the request if the failure was transient network error.
- Ensure the request/response objects are not disposed or aborted before the response is consumed.
- Validate the served content is a valid package before consuming it.
Example fix
// before
var resp = req.GetResponse();
var s = resp.GetResponseStream(); // WebResponseFailure here
// after
try {
var s = req.GetResponse().GetResponseStream();
} catch (WebException ex) {
// inspect ex.Status / inner exception, retry or surface
} Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: ensure request not disposed and outer transport URI is reachable
if (req == null || req.RequestUri.HostNameType == UriHostNameType.Unknown) throw new InvalidOperationException("invalid pack request"); Try / catch
try { return resp.GetResponseStream(); }
catch (WebException ex) when (ex.Status == WebExceptionStatus.ConnectFailure || ex.Status == WebExceptionStatus.Timeout) { /* retry with backoff */ }
catch (WebException ex) { /* surface inner exception ex.InnerException */ throw; } Prevention
- Consume the response promptly and don't dispose the request mid-flight
- Inspect WebException.Status and InnerException to find the root cause
- Implement retry with backoff for transient network errors
- Validate that the served bytes form a valid package before use
When it happens
Trigger: Accessing any PackWebResponse result member after the asynchronous response worker failed — e.g. underlying WebRequest.GetResponse threw, stream read failed, or container open failed on the worker thread.
Common situations: Network failure or server error while downloading the outer package; invalid package bytes that break Package.Open on the background thread; aborted/disposed request racing with a response access.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- WebResponsePartNotFound
- ' ' cannot contain the path delimiter: ' '.
- ' ' cannot start with the reserved character range…
- ' ' ID is not a valid XSD ID.
- ' ' is not a valid value for ' '.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/d11f3ada1fbdb647.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/IO/Packaging/PackWebResponse.cs:847
/// </summary>
private void WaitForResponse()
{
#if DEBUG
if (PackWebRequestFactory._traceSwitch.Enabled)
System.Diagnostics.Trace.TraceInformation(
DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
Environment.CurrentManagedThreadId + ": " +
"PackWebResponse.WaitForResponse()");
#endif
// wait for the response callback
_responseAvailable.WaitOne();
// We get here only when the other thread signals.
// Need to inspect for errors and throw if there was trouble on the other thread.
if (_responseError)
{
if (_responseException == null)
throw new WebException(SR.WebResponseFailure);
else
throw _responseException; // throw literal exception if there is one
}
}
/// <summary>
/// Timeout callback
/// </summary>
/// <param name="stateInfo"></param>
private void TimeoutCallback(Object stateInfo)
{
lock (_lockObject) // prevent race condition accessing _timeoutTimer, _disposed, _responseAvailable
{
// If disposed, the message is too late
// Exit early and don't access members as they have been disposed
// Let Close() method clean up our Timer object
if (_disposed)
return;View on GitHub (pinned to 81131a70a4)