diff --git a/lib/src/hosted_source.dart b/lib/src/hosted_source.dart
index 43922a21aae3287698e9f5f1fbe9737159b927a7..70b1440d297f093da1e20b8aad333f857786939e 100644
--- a/lib/src/hosted_source.dart
+++ b/lib/src/hosted_source.dart
@@ -119,6 +119,8 @@ class HostedSource extends Source {
   /// this tries to translate into a more user friendly error message. Always
   /// throws an error, either the original one or a better one.
   void _throwFriendlyError(ex, package, url) {
+    ex = getRealError(ex);
+
     if (ex is PubHttpException && ex.response.statusCode == 404) {
       throw 'Could not find package "$package" at $url.';
     }
diff --git a/lib/src/http.dart b/lib/src/http.dart
index 7218562f0868ecb1831884f513b09313fd4b2f7d..1c349786a1ced8b7f98f52838cdb8452ed3675cc 100644
--- a/lib/src/http.dart
+++ b/lib/src/http.dart
@@ -14,6 +14,7 @@ import '../../pkg/http/lib/http.dart' as http;
 import 'curl_client.dart';
 import 'io.dart';
 import 'log.dart' as log;
+import 'utils.dart';
 
 // TODO(nweiz): make this configurable
 /// The amount of time in milliseconds to allow HTTP requests before assuming
@@ -57,6 +58,7 @@ class PubHttpClient extends http.BaseClient {
         throw new PubHttpException(response);
       });
     }).catchError((e) {
+      e = getRealError(e);
       if (e is SocketIOException &&
           e.osError != null &&
           (e.osError.errorCode == 8 ||
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index b922d845d4013de9e3132acb6033f3e2e5fa86b4..544a3ce0bef5c1c9a9d99dc98154aa04694a91d3 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -183,3 +183,14 @@ void mapAddAll(Map destination, Map source) =>
 /// replacing `+` with ` `.
 String urlDecode(String encoded) =>
   decodeUriComponent(encoded.replaceAll("+", " "));
+
+// TODO(rnystrom): Remove this when #7781 is fixed.
+/// When an error is rethrown in an async callback, you can end up with nested
+/// AsyncErrors. This unwraps them to find the real originating error.
+getRealError(error) {
+  while (error is AsyncError) {
+    error = error.error;
+  }
+
+  return error;
+}