diff --git a/core/Command/Maintenance/Install.php b/core/Command/Maintenance/Install.php
index dffbbd0338217ec17b12f6c3ab8205a15ccec149..fc219e79bcdd42591341dd18ddd394ba1802e969 100644
--- a/core/Command/Maintenance/Install.php
+++ b/core/Command/Maintenance/Install.php
@@ -43,6 +43,8 @@ use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Question\Question;
+use Throwable;
+use function get_class;
 
 class Install extends Command {
 
@@ -201,11 +203,26 @@ class Install extends Command {
 	protected function printErrors(OutputInterface $output, $errors) {
 		foreach ($errors as $error) {
 			if (is_array($error)) {
-				$output->writeln('<error>' . (string)$error['error'] . '</error>');
-				$output->writeln('<info> -> ' . (string)$error['hint'] . '</info>');
+				$output->writeln('<error>' . $error['error'] . '</error>');
+				if (isset($error['hint']) && !empty($error['hint'])) {
+					$output->writeln('<info> -> ' . $error['hint'] . '</info>');
+				}
+				if (isset($error['exception']) && $error['exception'] instanceof Throwable) {
+					$this->printThrowable($output, $error['exception']);
+				}
 			} else {
-				$output->writeln('<error>' . (string)$error . '</error>');
+				$output->writeln('<error>' . $error . '</error>');
 			}
 		}
 	}
+
+	private function printThrowable(OutputInterface $output, Throwable $t): void {
+		$output->write('<info>Trace: ' . $t->getTraceAsString() . '</info>');
+		$output->writeln('');
+		if ($t->getPrevious() !== null) {
+			$output->writeln('');
+			$output->writeln('<info>Previous: ' . get_class($t->getPrevious()) . ': ' . $t->getPrevious()->getMessage() . '</info>');
+			$this->printThrowable($output, $t->getPrevious());
+		}
+	}
 }
diff --git a/lib/private/Setup.php b/lib/private/Setup.php
index 873e82e55de7f254667d97adcca624ff613ddd94..98cf11e3a87c33e39808243f59359f3293f9b67b 100644
--- a/lib/private/Setup.php
+++ b/lib/private/Setup.php
@@ -236,6 +236,7 @@ class Setup {
 			} catch (\OC\HintException $e) {
 				$errors[] = [
 					'error' => $e->getMessage(),
+					'exception' => $e,
 					'hint' => $e->getHint(),
 				];
 				$htAccessWorking = false;
@@ -360,12 +361,14 @@ class Setup {
 		} catch (\OC\DatabaseSetupException $e) {
 			$error[] = [
 				'error' => $e->getMessage(),
+				'exception' => $e,
 				'hint' => $e->getHint(),
 			];
 			return $error;
 		} catch (Exception $e) {
 			$error[] = [
 				'error' => 'Error while trying to create admin user: ' . $e->getMessage(),
+				'exception' => $e,
 				'hint' => '',
 			];
 			return $error;
@@ -376,6 +379,7 @@ class Setup {
 		} catch (Exception $e) {
 			$error[] = [
 				'error' => 'Error while trying to initialise the database: ' . $e->getMessage(),
+				'exception' => $e,
 				'hint' => '',
 			];
 			return $error;
diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php
index 54542de72bffdde4b6e44f3d92c7b946b374ece2..966c97edf553853aba0510455a1db7d1a177c913 100644
--- a/lib/private/Setup/MySQL.php
+++ b/lib/private/Setup/MySQL.php
@@ -66,7 +66,7 @@ class MySQL extends AbstractDatabase {
 		} catch (\Exception $e) {
 			$this->logger->logException($e);
 			throw new \OC\DatabaseSetupException($this->trans->t('MySQL username and/or password not valid'),
-				$this->trans->t('You need to enter details of an existing account.'));
+				$this->trans->t('You need to enter details of an existing account.'), 0, $e);
 		}
 	}
 
diff --git a/lib/private/Setup/OCI.php b/lib/private/Setup/OCI.php
index 1d7fe27e8b8df2e416ae855efa893684b32ddc47..ed05e0bf14c9ec916d67549687c6bf6170baebd7 100644
--- a/lib/private/Setup/OCI.php
+++ b/lib/private/Setup/OCI.php
@@ -74,14 +74,14 @@ class OCI extends AbstractDatabase {
 					. ' ORACLE_SID=' . getenv('ORACLE_SID')
 					. ' LD_LIBRARY_PATH=' . getenv('LD_LIBRARY_PATH')
 					. ' NLS_LANG=' . getenv('NLS_LANG')
-					. ' tnsnames.ora is ' . (is_readable(getenv('ORACLE_HOME') . '/network/admin/tnsnames.ora') ? '' : 'not ') . 'readable');
+					. ' tnsnames.ora is ' . (is_readable(getenv('ORACLE_HOME') . '/network/admin/tnsnames.ora') ? '' : 'not ') . 'readable', 0, $e);
 			}
 			throw new \OC\DatabaseSetupException($this->trans->t('Oracle username and/or password not valid'),
 				'Check environment: ORACLE_HOME=' . getenv('ORACLE_HOME')
 				. ' ORACLE_SID=' . getenv('ORACLE_SID')
 				. ' LD_LIBRARY_PATH=' . getenv('LD_LIBRARY_PATH')
 				. ' NLS_LANG=' . getenv('NLS_LANG')
-				. ' tnsnames.ora is ' . (is_readable(getenv('ORACLE_HOME') . '/network/admin/tnsnames.ora') ? '' : 'not ') . 'readable');
+				. ' tnsnames.ora is ' . (is_readable(getenv('ORACLE_HOME') . '/network/admin/tnsnames.ora') ? '' : 'not ') . 'readable', 0, $e);
 		}
 
 		$this->config->setValues([
diff --git a/lib/private/Setup/PostgreSQL.php b/lib/private/Setup/PostgreSQL.php
index 3d7a0b2a4b13d30dffe0a2bd82c68b4bb30e7f49..1f0b7b8f8948dca0f40325710a920c16ffbbe01e 100644
--- a/lib/private/Setup/PostgreSQL.php
+++ b/lib/private/Setup/PostgreSQL.php
@@ -99,7 +99,7 @@ class PostgreSQL extends AbstractDatabase {
 		} catch (\Exception $e) {
 			$this->logger->logException($e);
 			throw new \OC\DatabaseSetupException($this->trans->t('PostgreSQL username and/or password not valid'),
-				$this->trans->t('You need to enter details of an existing account.'));
+				$this->trans->t('You need to enter details of an existing account.'), 0, $e);
 		}
 	}