diff --git a/lib/src/pubspec.dart b/lib/src/pubspec.dart
index 6da96ba621cc6f2456a9a5bc41e00cc99bd0ac71..df7ebd93a349fe20ea8f8f4e84f4af605e59b990 100644
--- a/lib/src/pubspec.dart
+++ b/lib/src/pubspec.dart
@@ -121,7 +121,6 @@ void _validateFieldUrl(url, String field) {
 
 Pubspec _parseMap(String filePath, Map map, SourceRegistry sources) {
   var name = null;
-  var version = Version.none;
 
   if (map.containsKey('name')) {
     name = map['name'];
@@ -131,9 +130,9 @@ Pubspec _parseMap(String filePath, Map map, SourceRegistry sources) {
     }
   }
 
-  if (map.containsKey('version')) {
-    version = new Version.parse(map['version']);
-  }
+  var version = _parseVersion(map['version'], (v) =>
+      'The pubspec "version" field should be a semantic version number, '
+      'but was "$v".');
 
   var dependencies = _parseDependencies(filePath, sources,
       map['dependencies']);
@@ -183,14 +182,9 @@ Pubspec _parseMap(String filePath, Map map, SourceRegistry sources) {
           '"$environmentYaml".');
     }
 
-    var sdkYaml = environmentYaml['sdk'];
-    if (sdkYaml is! String) {
-      throw new FormatException(
-          'The "sdk" field of "environment" should be a string, but was '
-          '"$sdkYaml".');
-    }
-
-    sdkConstraint = new VersionConstraint.parse(sdkYaml);
+    sdkConstraint = _parseVersionConstraint(environmentYaml['sdk'], (v) =>
+        'The "sdk" field of "environment" should be a semantic version '
+        'constraint, but was "$v".');
   }
   var environment = new PubspecEnvironment(sdkConstraint);
 
@@ -241,6 +235,36 @@ Pubspec _parseMap(String filePath, Map map, SourceRegistry sources) {
       environment, map);
 }
 
+/// Parses [yaml] to a [Version] or throws a [FormatException] with the result
+/// of calling [message] if it isn't valid.
+///
+/// If [yaml] is `null`, returns [Version.none].
+Version _parseVersion(yaml, String message(yaml)) {
+  if (yaml == null) return Version.none;
+  if (yaml is! String) throw new FormatException(message(yaml));
+
+  try {
+    return new Version.parse(yaml);
+  } on FormatException catch(_) {
+    throw new FormatException(message(yaml));
+  }
+}
+
+/// Parses [yaml] to a [VersionConstraint] or throws a [FormatException] with
+/// the result of calling [message] if it isn't valid.
+///
+/// If [yaml] is `null`, returns [VersionConstraint.any].
+VersionConstraint _parseVersionConstraint(yaml, String getMessage(yaml)) {
+  if (yaml == null) return VersionConstraint.any;
+  if (yaml is! String) throw new FormatException(getMessage(yaml));
+
+  try {
+    return new VersionConstraint.parse(yaml);
+  } on FormatException catch(_) {
+    throw new FormatException(getMessage(yaml));
+  }
+}
+
 List<PackageDep> _parseDependencies(String pubspecPath, SourceRegistry sources,
     yaml) {
   var dependencies = <PackageDep>[];
@@ -268,7 +292,9 @@ List<PackageDep> _parseDependencies(String pubspecPath, SourceRegistry sources,
       versionConstraint = new VersionConstraint.parse(spec);
     } else if (spec is Map) {
       if (spec.containsKey('version')) {
-        versionConstraint = new VersionConstraint.parse(spec.remove('version'));
+        versionConstraint = _parseVersionConstraint(spec.remove('version'),
+            (v) => 'The "version" field for $name should be a semantic '
+                   'version constraint, but was "$v".');
       }
 
       var sourceNames = spec.keys.toList();
diff --git a/test/pubspec_test.dart b/test/pubspec_test.dart
index 47f838a0a7f2fb895a1e9e4f8ac3ce7e6c6748bf..e7608b4cfc375908fd99a6d71b58439d4ac6c997 100644
--- a/test/pubspec_test.dart
+++ b/test/pubspec_test.dart
@@ -111,10 +111,40 @@ dependencies:
 ''');
     });
 
+    test("throws if dependency version is not a string", () {
+      expectFormatError('''
+dependencies:
+  foo:
+    mock: ok
+    version: 1.2
+''');
+    });
+
+    test("throws if version is not a version constraint", () {
+      expectFormatError('''
+dependencies:
+  foo:
+    mock: ok
+    version: not constraint
+''');
+    });
+
     test("throws if 'name' is not a string", () {
       expectFormatError('name: [not, a, string]');
     });
 
+    test("throws if version is not a string", () {
+      expectFormatError('''
+version: 1.0
+''');
+    });
+
+    test("throws if version is not a version", () {
+      expectFormatError('''
+version: not version
+''');
+    });
+
     test("throws if 'homepage' is not a string", () {
       expectFormatError('homepage:');
       expectFormatError('homepage: [not, a, string]');
@@ -212,6 +242,13 @@ environment:
 ''');
       });
 
+    test("throws if the sdk is not a string", () {
+      expectFormatError('''
+environment:
+  sdk: 1.0
+''');
+    });
+
       test("throws if the sdk isn't a valid version constraint", () {
         expectFormatError('''
 environment: