diff --git a/lib/daemon.py b/lib/daemon.py
index eceeac4061f40a620edfb471abcb8ef4c6722748..ba5f17504134e6148e22506cf9ec85a74bd1a179 100644
--- a/lib/daemon.py
+++ b/lib/daemon.py
@@ -624,22 +624,34 @@ def GenericMain(daemon_name, optionparser,
 
   if options.fork:
     utils.CloseFDs()
-    utils.Daemonize(logfile=constants.DAEMONS_LOGFILES[daemon_name])
+    wpipe = utils.Daemonize(logfile=constants.DAEMONS_LOGFILES[daemon_name])
+  else:
+    wpipe = None
 
   utils.WritePidFile(utils.DaemonPidFileName(daemon_name))
   try:
-    utils.SetupLogging(logfile=constants.DAEMONS_LOGFILES[daemon_name],
-                       debug=options.debug,
-                       stderr_logging=not options.fork,
-                       multithreaded=multithreaded,
-                       program=daemon_name,
-                       syslog=options.syslog,
-                       console_logging=console_logging)
-    logging.info("%s daemon startup", daemon_name)
-    if callable(prepare_fn):
-      prep_results = prepare_fn(options, args)
-    else:
-      prep_results = None
+    try:
+      utils.SetupLogging(logfile=constants.DAEMONS_LOGFILES[daemon_name],
+                         debug=options.debug,
+                         stderr_logging=not options.fork,
+                         multithreaded=multithreaded,
+                         program=daemon_name,
+                         syslog=options.syslog,
+                         console_logging=console_logging)
+      if callable(prepare_fn):
+        prep_results = prepare_fn(options, args)
+      else:
+        prep_results = None
+      logging.info("%s daemon startup", daemon_name)
+    except Exception, err:
+      if wpipe is not None:
+        os.write(wpipe, str(err))
+      raise
+
+    if wpipe is not None:
+      # we're done with the preparation phase, we close the pipe to
+      # let the parent know it's safe to exit
+      os.close(wpipe)
 
     exec_fn(options, args, prep_results)
   finally:
diff --git a/lib/utils.py b/lib/utils.py
index 9e04d980e0bcc59168c298e238ff50b4deb0f62e..54588cf89ffcc3592a11190d1e2463f9da959b16 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -348,8 +348,8 @@ def StartDaemon(cmd, env=None, cwd="/", output=None, output_fd=None,
         finally:
           _CloseFDNoErr(errpipe_write)
 
-        # Wait for daemon to be started (or an error message to arrive) and read
-        # up to 100 KB as an error message
+        # Wait for daemon to be started (or an error message to
+        # arrive) and read up to 100 KB as an error message
         errormsg = RetryOnSignal(os.read, errpipe_read, 100 * 1024)
       finally:
         _CloseFDNoErr(errpipe_read)
@@ -2146,6 +2146,12 @@ def Daemonize(logfile):
   # pylint: disable-msg=W0212
   # yes, we really want os._exit
 
+  # TODO: do another attempt to merge Daemonize and StartDaemon, or at
+  # least abstract the pipe functionality between them
+
+  # Create pipe for sending error messages
+  (rpipe, wpipe) = os.pipe()
+
   # this might fail
   pid = os.fork()
   if (pid == 0):  # The first child.
@@ -2154,15 +2160,24 @@ def Daemonize(logfile):
     # this might fail
     pid = os.fork() # Fork a second child.
     if (pid == 0):  # The second child.
-      pass # nothing special to do in the child
+      _CloseFDNoErr(rpipe)
     else:
       # exit() or _exit()?  See below.
       os._exit(0) # Exit parent (the first child) of the second child.
   else:
-    os._exit(0) # Exit parent of the first child.
+    _CloseFDNoErr(wpipe)
+    # Wait for daemon to be started (or an error message to
+    # arrive) and read up to 100 KB as an error message
+    errormsg = RetryOnSignal(os.read, rpipe, 100 * 1024)
+    if errormsg:
+      sys.stderr.write("Error when starting daemon process: %r\n" % errormsg)
+      rcode = 1
+    else:
+      rcode = 0
+    os._exit(rcode) # Exit parent of the first child.
 
   SetupDaemonFDs(logfile, None)
-  return 0
+  return wpipe
 
 
 def DaemonPidFileName(name):