diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 228b1067bb01a..01fc97314c263 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -11061,7 +11061,7 @@ namespace ts {
             let someHaveQuestionToken = false;
             let allHaveQuestionToken = true;
             let hasOverloads = false;
-            let bodyDeclaration: FunctionLikeDeclaration;
+            let implementationDeclaration: FunctionLikeDeclaration; // should be the first declaration with a body
             let lastSeenNonAmbientDeclaration: FunctionLikeDeclaration;
             let previousDeclaration: FunctionLikeDeclaration;
 
@@ -11143,12 +11143,17 @@ namespace ts {
                     someHaveQuestionToken = someHaveQuestionToken || hasQuestionToken(node);
                     allHaveQuestionToken = allHaveQuestionToken && hasQuestionToken(node);
 
-                    if (nodeIsPresent(node.body) && bodyDeclaration) {
+                    if (nodeIsPresent(node.body) && implementationDeclaration) {
                         if (isConstructor) {
                             multipleConstructorImplementation = true;
                         }
                         else {
                             duplicateFunctionDeclaration = true;
+
+                            // We expect both implementations to agree in defaultness for later on.
+                            if ((node.flags & NodeFlags.Default) !== (implementationDeclaration.flags & NodeFlags.Default)) {
+                                Debug.fail("Expected first and current implementations of and current to agree in export default flag.");
+                            }
                         }
                     }
                     else if (!isExportSymbolInsideModule && previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) {
@@ -11156,8 +11161,8 @@ namespace ts {
                     }
 
                     if (nodeIsPresent(node.body)) {
-                        if (!bodyDeclaration) {
-                            bodyDeclaration = node;
+                        if (!implementationDeclaration) {
+                            implementationDeclaration = node;
                         }
                     }
                     else {
@@ -11173,15 +11178,19 @@ namespace ts {
             }
 
             if (multipleConstructorImplementation) {
-                forEach(declarations, declaration => {
+                for (let declaration of declarations) {
                     error(declaration, Diagnostics.Multiple_constructor_implementations_are_not_allowed);
-                });
+                }
             }
 
             if (duplicateFunctionDeclaration) {
-                forEach(declarations, declaration => {
-                    error(declaration.name, Diagnostics.Duplicate_function_implementation);
-                });
+                let message = implementationDeclaration.flags & NodeFlags.Default && areAllFunctionDeclarationsWhereSomeNamesDiffer(declarations) ?
+                    Diagnostics.A_module_cannot_have_multiple_default_exports :
+                    Diagnostics.Duplicate_function_implementation;
+
+                for (let declaration of declarations) {
+                    error(declaration.name || declaration, message);
+                }
             }
 
             // Abstract methods can't have an implementation -- in particular, they don't need one.
@@ -11191,12 +11200,12 @@ namespace ts {
             }
 
             if (hasOverloads) {
-                checkFlagAgreementBetweenOverloads(declarations, bodyDeclaration, flagsToCheck, someNodeFlags, allNodeFlags);
-                checkQuestionTokenAgreementBetweenOverloads(declarations, bodyDeclaration, someHaveQuestionToken, allHaveQuestionToken);
+                checkFlagAgreementBetweenOverloads(declarations, implementationDeclaration, flagsToCheck, someNodeFlags, allNodeFlags);
+                checkQuestionTokenAgreementBetweenOverloads(declarations, implementationDeclaration, someHaveQuestionToken, allHaveQuestionToken);
 
-                if (bodyDeclaration) {
+                if (implementationDeclaration) {
                     let signatures = getSignaturesOfSymbol(symbol);
-                    let bodySignature = getSignatureFromDeclaration(bodyDeclaration);
+                    let bodySignature = getSignatureFromDeclaration(implementationDeclaration);
                     // If the implementation signature has string literals, we will have reported an error in
                     // checkSpecializedSignatureDeclaration
                     if (!bodySignature.hasStringLiterals) {
@@ -11225,6 +11234,56 @@ namespace ts {
             }
         }
 
+        /**
+         * Determines if all declarations in the given list are function declarations, and that
+         * all the declarations have the same name. This is useful for how we report errors.
+         *
+         * For instance, if a user has
+         *
+         *      export default function foo() { }
+         *      export default function bar() { }
+         *
+         * We want to tell the user that there are multiple default exports. However, if a user has
+         *
+         *      export default function foo() { }
+         *      export default function foo() { }
+         *
+         * It is probably more accurate to say that there are duplicate function implementations.
+         * 
+         * @param declarations
+         */
+        function areAllFunctionDeclarationsWhereSomeNamesDiffer(declarations: Declaration[]) {
+            let numDeclarations = declarations.length;
+            Debug.assert(numDeclarations > 0, "Expected at least one declaration.");
+
+            let firstDeclaration = declarations[0];
+            if (firstDeclaration.kind !== SyntaxKind.FunctionDeclaration) {
+                return false;
+            }
+
+            let firstName = (firstDeclaration as FunctionDeclaration).name;
+            for (let i = 1; i < numDeclarations; i++) {
+                let currentDeclaration = declarations[i];
+                if (currentDeclaration.kind !== SyntaxKind.FunctionDeclaration) {
+                    return false;
+                }
+
+                let currentName = (currentDeclaration as FunctionDeclaration).name;
+                if (currentName) {
+                    if (!firstName || currentName.text !== firstName.text) {
+                        // Either 'firstName' must be undefined or the text must differ.
+                        return true;
+                    }
+                }
+                else if (firstName) {
+                    // 'currentName' is not defined but 'firstName' is.
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
         function checkExportsOnMergedDeclarations(node: Node): void {
             if (!produceDiagnostics) {
                 return;
diff --git a/tests/baselines/reference/multipleDefaultExports02.errors.txt b/tests/baselines/reference/multipleDefaultExports02.errors.txt
index 235f8f7c3e374..d6b9009b60381 100644
--- a/tests/baselines/reference/multipleDefaultExports02.errors.txt
+++ b/tests/baselines/reference/multipleDefaultExports02.errors.txt
@@ -1,18 +1,18 @@
-tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2393: Duplicate function implementation.
-tests/cases/conformance/es6/modules/m1.ts(6,25): error TS2393: Duplicate function implementation.
+tests/cases/conformance/es6/modules/m1.ts(2,25): error TS2528: A module cannot have multiple default exports.
+tests/cases/conformance/es6/modules/m1.ts(6,25): error TS2528: A module cannot have multiple default exports.
 
 
 ==== tests/cases/conformance/es6/modules/m1.ts (2 errors) ====
     
     export default function foo() {
                             ~~~
-!!! error TS2393: Duplicate function implementation.
+!!! error TS2528: A module cannot have multiple default exports.
     
     }
     
     export default function bar() {
                             ~~~
-!!! error TS2393: Duplicate function implementation.
+!!! error TS2528: A module cannot have multiple default exports.
     
     }
     
diff --git a/tests/baselines/reference/multipleDefaultExports05.errors.txt b/tests/baselines/reference/multipleDefaultExports05.errors.txt
new file mode 100644
index 0000000000000..5edcfc914c77d
--- /dev/null
+++ b/tests/baselines/reference/multipleDefaultExports05.errors.txt
@@ -0,0 +1,62 @@
+tests/cases/conformance/es6/modules/m1.ts(2,1): error TS2393: Duplicate function implementation.
+tests/cases/conformance/es6/modules/m1.ts(6,1): error TS2393: Duplicate function implementation.
+tests/cases/conformance/es6/modules/m2.ts(1,1): error TS2528: A module cannot have multiple default exports.
+tests/cases/conformance/es6/modules/m2.ts(5,1): error TS2528: A module cannot have multiple default exports.
+tests/cases/conformance/es6/modules/m3.ts(1,1): error TS2528: A module cannot have multiple default exports.
+tests/cases/conformance/es6/modules/m3.ts(5,22): error TS2528: A module cannot have multiple default exports.
+tests/cases/conformance/es6/modules/m4.ts(1,25): error TS2528: A module cannot have multiple default exports.
+tests/cases/conformance/es6/modules/m4.ts(5,1): error TS2528: A module cannot have multiple default exports.
+
+
+==== tests/cases/conformance/es6/modules/m1.ts (2 errors) ====
+    
+    export default function () {
+    ~~~~~~
+!!! error TS2393: Duplicate function implementation.
+    
+    }
+    
+    export default function () {
+    ~~~~~~
+!!! error TS2393: Duplicate function implementation.
+    
+    }
+    
+==== tests/cases/conformance/es6/modules/m2.ts (2 errors) ====
+    export default function () {
+    ~~~~~~
+!!! error TS2528: A module cannot have multiple default exports.
+    
+    }
+    
+    export default class {
+    ~~~~~~
+!!! error TS2528: A module cannot have multiple default exports.
+    
+    }
+    
+==== tests/cases/conformance/es6/modules/m3.ts (2 errors) ====
+    export default function () {
+    ~~~~~~
+!!! error TS2528: A module cannot have multiple default exports.
+    
+    }
+    
+    export default class C {
+                         ~
+!!! error TS2528: A module cannot have multiple default exports.
+    
+    }
+    
+==== tests/cases/conformance/es6/modules/m4.ts (2 errors) ====
+    export default function f() {
+                            ~
+!!! error TS2528: A module cannot have multiple default exports.
+    
+    }
+    
+    export default class {
+    ~~~~~~
+!!! error TS2528: A module cannot have multiple default exports.
+    
+    }
\ No newline at end of file
diff --git a/tests/baselines/reference/multipleDefaultExports05.js b/tests/baselines/reference/multipleDefaultExports05.js
new file mode 100644
index 0000000000000..67458900bf9d2
--- /dev/null
+++ b/tests/baselines/reference/multipleDefaultExports05.js
@@ -0,0 +1,84 @@
+//// [tests/cases/conformance/es6/modules/multipleDefaultExports05.ts] ////
+
+//// [m1.ts]
+
+export default function () {
+
+}
+
+export default function () {
+
+}
+
+//// [m2.ts]
+export default function () {
+
+}
+
+export default class {
+
+}
+
+//// [m3.ts]
+export default function () {
+
+}
+
+export default class C {
+
+}
+
+//// [m4.ts]
+export default function f() {
+
+}
+
+export default class {
+
+}
+
+//// [m1.js]
+function default_1() {
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = default_1;
+function default_2() {
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = default_2;
+//// [m2.js]
+function default_1() {
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = default_1;
+var default_2 = (function () {
+    function default_2() {
+    }
+    return default_2;
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = default_2;
+//// [m3.js]
+function default_1() {
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = default_1;
+var C = (function () {
+    function C() {
+    }
+    return C;
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = C;
+//// [m4.js]
+function f() {
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = f;
+var default_1 = (function () {
+    function default_1() {
+    }
+    return default_1;
+})();
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = default_1;
diff --git a/tests/cases/conformance/es6/modules/multipleDefaultExports05.ts b/tests/cases/conformance/es6/modules/multipleDefaultExports05.ts
new file mode 100644
index 0000000000000..e90b175d779bc
--- /dev/null
+++ b/tests/cases/conformance/es6/modules/multipleDefaultExports05.ts
@@ -0,0 +1,38 @@
+// @module: commonjs
+// @target: ES5
+
+// @filename: m1.ts
+export default function () {
+
+}
+
+export default function () {
+
+}
+
+// @filename: m2.ts
+export default function () {
+
+}
+
+export default class {
+
+}
+
+// @filename: m3.ts
+export default function () {
+
+}
+
+export default class C {
+
+}
+
+// @filename: m4.ts
+export default function f() {
+
+}
+
+export default class {
+
+}
\ No newline at end of file