diff --git a/Sources/Common.swift b/Sources/Common.swift
index 6931a6af..1a79886d 100644
--- a/Sources/Common.swift
+++ b/Sources/Common.swift
@@ -149,6 +149,12 @@ extension MustacheError : CustomStringConvertible {
     }
 }
 
+// Make the `localizedDescription` property of an `Error` be the same as the `description`
+extension MustacheError : LocalizedError {
+    public var errorDescription: String? {
+        return description
+    }
+}
 
 /// A pair of tag delimiters, such as `("{{", "}}")`.
 ///
diff --git a/Sources/Configuration.swift b/Sources/Configuration.swift
index 18b83f7f..4d6474c0 100644
--- a/Sources/Configuration.swift
+++ b/Sources/Configuration.swift
@@ -93,6 +93,7 @@ public struct Configuration {
         contentType = .html
         baseContext = Context()
         tagDelimiterPair = ("{{", "}}")
+        throwWhenMissing = false
     }
     
     
@@ -295,6 +296,14 @@ public struct Configuration {
     /// You can also change the delimiters right in your templates using a "Set
     /// Delimiter tag": `{{=[[ ]]=}}` changes delimiters to `[[` and `]]`.
     public var tagDelimiterPair: TagDelimiterPair
+
+    // =========================================================================
+    // MARK: - Render configuration
+
+    /// Throw an error during rendering when a tag found in the template
+    /// is missing from the context, or the tag is in the context but its
+    /// value is nil.
+    public var throwWhenMissing: Bool
 }
 
 
diff --git a/Sources/ExpressionInvocation.swift b/Sources/ExpressionInvocation.swift
index a06da269..cf003839 100644
--- a/Sources/ExpressionInvocation.swift
+++ b/Sources/ExpressionInvocation.swift
@@ -39,14 +39,26 @@ struct ExpressionInvocation {
             
         case .identifier(let identifier):
             // {{ identifier }}
-            
-            return context.mustacheBox(forKey: identifier)
+
+            let identifierBox = context.mustacheBox(forKey: identifier)
+
+            if DefaultConfiguration.throwWhenMissing, identifierBox.isEmpty {
+                throw MustacheError(kind: .renderError, message: "Missing identifier")
+            }
+
+            return identifierBox
 
         case .scoped(let baseExpression, let identifier):
             // {{ <expression>.identifier }}
-            
-            return try evaluate(context: context, expression: baseExpression).mustacheBox(forKey: identifier)
-            
+
+            let identifierBox = try evaluate(context: context, expression: baseExpression).mustacheBox(forKey: identifier)
+
+            if DefaultConfiguration.throwWhenMissing, identifierBox.isEmpty {
+                throw MustacheError(kind: .renderError, message: "Missing identifier")
+            }
+
+            return identifierBox
+
         case .filter(let filterExpression, let argumentExpression, let partialApplication):
             // {{ <expression>(<expression>) }}
             
diff --git a/Tests/Public/BoxTestsWithMissingIndentifiers.swift b/Tests/Public/BoxTestsWithMissingIndentifiers.swift
new file mode 100644
index 00000000..e61e2add
--- /dev/null
+++ b/Tests/Public/BoxTestsWithMissingIndentifiers.swift
@@ -0,0 +1,95 @@
+import XCTest
+import Mustache
+
+class BoxTestsWithMissingIndentifiers: XCTestCase {
+    override func setUp() {
+        super.setUp()
+
+        DefaultConfiguration.throwWhenMissing = true
+    }
+
+    override func tearDown() {
+        super.tearDown()
+
+        DefaultConfiguration.throwWhenMissing = false
+    }
+
+    func testIdentifier() {
+        do {
+            // Key exists, but value is nil
+            let value: [String: Any?] = ["string": "foo", "missing": nil]
+            let template = try! Template(string: "{{string}}, {{missing}}")
+            assert(try template.render(value), throws: missingErrorDescription("missing", 1))
+        }
+
+        do {
+            // Key does not exist
+            let value: [String: Any?] = ["string": "foo"]
+            let template = try! Template(string: "{{string}}, {{missing}}")
+            assert(try template.render(value), throws: missingErrorDescription("missing", 1))
+        }
+    }
+
+    func testIdentifierWithSubscript() {
+        do {
+            // Key exists, but value is nil
+            let value: [String: Any?] = ["string": "foo", "subscript": ["int": 1, "missing": nil]]
+            let template = try! Template(string: "{{string}}, {{subscript.int}}, {{subscript.missing}}")
+            assert(try template.render(value), throws: missingErrorDescription("subscript.missing", 1))
+        }
+
+        do {
+            // Key does not exist
+            let value: [String: Any?] = ["string": "foo", "subscript": ["int": 1]]
+            let template = try! Template(string: "{{string}}, {{subscript.int}}, {{subscript.missing}}")
+            assert(try template.render(value), throws: missingErrorDescription("subscript.missing", 1))
+        }
+    }
+
+    func testSection() {
+        do {
+            // Key exists, but value is nil
+            let value: [String: Any?] = ["section": ["int": 1, "missing": nil]]
+            let template = try! Template(string: "{{#section}}{{int}}, {{missing}}{{/section}}")
+            assert(try template.render(value), throws: missingErrorDescription("missing", 1))
+        }
+
+        do {
+            // Key does not exist
+            let value: [String: Any?] = ["section": ["int": 1]]
+            let template = try! Template(string: "{{#section}}{{int}}, {{missing}}{{/section}}")
+            assert(try template.render(value), throws: missingErrorDescription("missing", 1))
+        }
+
+        do {
+            // Section does not exist
+            let value: [String: Any?] = [:]
+            let template = try! Template(string: "{{#section}}{{int}}, {{missing}}{{/section}}")
+            assert(try template.render(value), throws: missingErrorDescription("#section", 1))
+        }
+    }
+}
+
+private func missingErrorDescription(_ label: String, _ lineNumber: Int) -> String {
+    return "Rendering error at line \(lineNumber): Could not evaluate {{\(label)}} at line \(lineNumber): Missing identifier"
+}
+
+// Inspired by https://www.swiftbysundell.com/articles/testing-error-code-paths-in-swift/
+private extension XCTestCase {
+    func assert<T>(
+        _ expression: @autoclosure () throws -> T,
+        throws errorDescription: String,
+        in file: StaticString = #file,
+        line: UInt = #line
+    ) {
+        var thrownError: Error?
+
+        XCTAssertThrowsError(try expression(), file: file, line: line) {
+            thrownError = $0
+        }
+
+        if let thrownError = thrownError {
+            XCTAssertEqual(thrownError.localizedDescription, errorDescription, file: file, line: line)
+        }
+    }
+}
diff --git a/Xcode/Mustache.xcodeproj/project.pbxproj b/Xcode/Mustache.xcodeproj/project.pbxproj
index 40779ece..2b3d147f 100644
--- a/Xcode/Mustache.xcodeproj/project.pbxproj
+++ b/Xcode/Mustache.xcodeproj/project.pbxproj
@@ -66,6 +66,9 @@
 		09A89E201BF58720003A695E /* FilterTests.mustache in Resources */ = {isa = PBXBuildFile; fileRef = 56CD9F651A275980001BABA4 /* FilterTests.mustache */; };
 		09A89E251BF62345003A695E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09A89E231BF58903003A695E /* UIKit.framework */; };
 		09A89E261BF62355003A695E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 09A89E211BF588EC003A695E /* Foundation.framework */; };
+		4176BD98237C15CD00250C0B /* BoxTestsWithMissingIndentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4176BD96237C15C700250C0B /* BoxTestsWithMissingIndentifiers.swift */; };
+		4176BD99237C15CE00250C0B /* BoxTestsWithMissingIndentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4176BD96237C15C700250C0B /* BoxTestsWithMissingIndentifiers.swift */; };
+		4176BD9A237C15CE00250C0B /* BoxTestsWithMissingIndentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4176BD96237C15C700250C0B /* BoxTestsWithMissingIndentifiers.swift */; };
 		5607A33C1C160216002364C1 /* GRMustacheKeyAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = 5607A33A1C160216002364C1 /* GRMustacheKeyAccess.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		5607A33D1C160216002364C1 /* GRMustacheKeyAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = 5607A33A1C160216002364C1 /* GRMustacheKeyAccess.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		5607A33E1C160216002364C1 /* GRMustacheKeyAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = 5607A33A1C160216002364C1 /* GRMustacheKeyAccess.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -313,6 +316,7 @@
 		09A89DDA1BF584EE003A695E /* MustacheTVOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MustacheTVOSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
 		09A89E211BF588EC003A695E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
 		09A89E231BF58903003A695E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
+		4176BD96237C15C700250C0B /* BoxTestsWithMissingIndentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxTestsWithMissingIndentifiers.swift; sourceTree = "<group>"; };
 		56056AA51A84CDBD0076BBAA /* TODO.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = TODO.md; path = ../TODO.md; sourceTree = "<group>"; };
 		5607A33A1C160216002364C1 /* GRMustacheKeyAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GRMustacheKeyAccess.h; sourceTree = "<group>"; };
 		5607A33B1C160216002364C1 /* GRMustacheKeyAccess.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRMustacheKeyAccess.m; sourceTree = "<group>"; };
@@ -798,6 +802,7 @@
 			isa = PBXGroup;
 			children = (
 				56C8D6E01A1F1A4700F106F8 /* BoxTests.swift */,
+				4176BD96237C15C700250C0B /* BoxTestsWithMissingIndentifiers.swift */,
 				5698AC1A1D9D31C30056AF8C /* BoxValueTests.swift */,
 				56FC9C831A17CD0C0020AAF8 /* ConfigurationTests */,
 				56FC9C881A17CD0C0020AAF8 /* ContextTests */,
@@ -1213,6 +1218,7 @@
 				09A89E0C1BF58702003A695E /* LambdaTests.swift in Sources */,
 				09A89E0F1BF58702003A695E /* RenderFunctionTests.swift in Sources */,
 				09A89E0A1BF58702003A695E /* HookFunctionTests.swift in Sources */,
+				4176BD9A237C15CE00250C0B /* BoxTestsWithMissingIndentifiers.swift in Sources */,
 				09A89E1E1BF58720003A695E /* FilterTests.swift in Sources */,
 				09A89E091BF58702003A695E /* FoundationCollectionTests.swift in Sources */,
 				09A89E101BF58709003A695E /* ConfigurationBaseContextTests.swift in Sources */,
@@ -1304,6 +1310,7 @@
 				561E72B51A8BDC6A004ED48B /* TemplateRepositoryDictionaryTests.swift in Sources */,
 				561E72B61A8BDC6A004ED48B /* TemplateRepositoryURLTests.swift in Sources */,
 				561E72A21A8BDC6A004ED48B /* MustacheBoxDocumentationTests.swift in Sources */,
+				4176BD99237C15CE00250C0B /* BoxTestsWithMissingIndentifiers.swift in Sources */,
 				561E72AF1A8BDC6A004ED48B /* StandardLibraryTests.swift in Sources */,
 				561E72B11A8BDC6A004ED48B /* TagTests.swift in Sources */,
 				566244A21AF1645F008BAD41 /* HoganSuite.swift in Sources */,
@@ -1393,6 +1400,7 @@
 				569C423B1A87D03800748E98 /* ContextRegisteredKeyTests.swift in Sources */,
 				5674F3751A1CC7B8000CE8CB /* FormatterTests.swift in Sources */,
 				56FC9C8E1A17CD0C0020AAF8 /* ContextValueForMustacheExpressionTests.swift in Sources */,
+				4176BD98237C15CD00250C0B /* BoxTestsWithMissingIndentifiers.swift in Sources */,
 				56FC9C8B1A17CD0C0020AAF8 /* ConfigurationContentTypeTests.swift in Sources */,
 				56FC9C8D1A17CD0C0020AAF8 /* ConfigurationTagDelimitersTests.swift in Sources */,
 				566244A11AF1645F008BAD41 /* HoganSuite.swift in Sources */,