diff --git a/guix/derivations.scm b/guix/derivations.scm
index ffdf570fc29fa0c44a2a491fc95bc0e740bf993c..24ee06c3996f82f88b27cef7bbe4530162c071fa 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -446,7 +446,9 @@ (define* (build-expression->derivation store name system exp inputs
 when SUB-DRV is omitted, \"out\" is assumed.  EXP is evaluated in an
 environment where %OUTPUT is bound to the main output path, %OUTPUTS is bound
 to a list of output/path pairs, and where %BUILD-INPUTS is bound to an alist
-of string/output-path pairs made from INPUTS."
+of string/output-path pairs made from INPUTS.  The builder terminates by
+passing the result of EXP to `exit'; thus, when EXP returns #f, the build is
+considered to have failed."
   (define guile
     (string-append (derivation-path->output-path (%guile-for-build))
                    "/bin/guile"))
@@ -472,7 +474,8 @@ (define %build-inputs
          (builder  (add-text-to-store store
                                       (string-append name "-guile-builder")
                                       (string-append (object->string prologue)
-                                                     (object->string exp))
+                                                     (object->string
+                                                      `(exit ,exp)))
                                       (map second inputs)))
          (mod-drv  (if (null? modules)
                        #f
diff --git a/tests/derivations.scm b/tests/derivations.scm
index 4a81a70f653382df44d0a90913affd5848164af9..1e9a136d04c662b1b3737909e3f8b9d6157a7509 100644
--- a/tests/derivations.scm
+++ b/tests/derivations.scm
@@ -29,6 +29,7 @@ (define-module (test-derivations)
   #:use-module (rnrs io ports)
   #:use-module (rnrs bytevectors)
   #:use-module (ice-9 rdelim)
+  #:use-module (ice-9 regex)
   #:use-module (ice-9 ftw)
   #:use-module (ice-9 match))
 
@@ -181,6 +182,20 @@ (define %coreutils
            (equal? '(hello guix)
                    (call-with-input-file (string-append p "/test") read))))))
 
+(test-assert "build-expression->derivation with expression returning #f"
+  (let* ((builder  '(begin
+                      (mkdir %output)
+                      #f))                        ; fail!
+         (drv-path (build-expression->derivation %store "fail" (%current-system)
+                                                 builder '())))
+    (guard (c ((nix-protocol-error? c)
+               ;; Note that the output path may exist at this point, but it
+               ;; is invalid.
+               (not (not (string-match "build .* failed"
+                                       (nix-protocol-error-message c))))))
+      (build-derivations %store (list drv-path))
+      #f)))
+
 (test-assert "build-expression->derivation with two outputs"
   (let* ((builder    '(begin
                         (call-with-output-file (assoc-ref %outputs "out")
@@ -265,4 +280,5 @@ (define %coreutils
 
 ;;; Local Variables:
 ;;; eval: (put 'test-assert 'scheme-indent-function 1)
+;;; eval: (put 'guard 'scheme-indent-function 1)
 ;;; End: