diff --git a/lib/SimpleSAML/Auth/Simple.php b/lib/SimpleSAML/Auth/Simple.php
index 552550d33e7b433cb417df070918e5aca04e4145..0909d9790bb341a9fb9284418d52a94fe3dd7eca 100644
--- a/lib/SimpleSAML/Auth/Simple.php
+++ b/lib/SimpleSAML/Auth/Simple.php
@@ -26,8 +26,8 @@ class Simple
      */
     protected string $authSource;
 
-    /** @var \SimpleSAML\Configuration */
-    protected Configuration $app_config;
+    /** @var \SimpleSAML\Configuration|null */
+    protected ?Configuration $app_config;
 
     /** @var \SimpleSAML\Session */
     protected Session $session;
@@ -46,8 +46,7 @@ class Simple
             $config = Configuration::getInstance();
         }
         $this->authSource = $authSource;
-        /** @psalm-var \SimpleSAML\Configuration $this->app_config */
-        $this->app_config = $config->getConfigItem('application');
+        $this->app_config = $config->getOptionalConfigItem('application', null);
 
         if ($session === null) {
             $session = Session::getSessionFromRequest();
diff --git a/lib/SimpleSAML/Configuration.php b/lib/SimpleSAML/Configuration.php
index fed916d882d6014837a868b0c406df85bc5f1253..71c4f0ea5b7713b1cadf4026771896e7a03fdfb3 100644
--- a/lib/SimpleSAML/Configuration.php
+++ b/lib/SimpleSAML/Configuration.php
@@ -972,41 +972,51 @@ class Configuration implements Utils\ClearableState
     /**
      * Retrieve an array as a \SimpleSAML\Configuration object.
      *
-     * This function will load the value of an option into a \SimpleSAML\Configuration object. The option must contain
-     * an array.
+     * This function will load the value of an option into a \SimpleSAML\Configuration object.
+     *   The option must contain an array.
      *
-     * An exception will be thrown if this option isn't an array, or if this option isn't found, and no default value
-     * is given.
+     * An exception will be thrown if this option isn't an array, or if this option isn't found.
      *
      * @param string $name The name of the option.
+     * @return \SimpleSAML\Configuration The option with the given name,
+     *
+     * @throws \SimpleSAML\Assert\AssertionFailedException If the option is not an array.
+     */
+    public function getConfigItem(string $name): Configuration
+    {
+        $ret = $this->getArray($name);
+
+        return self::loadFromArray($ret, $this->location . '[' . var_export($name, true) . ']');
+    }
+
+
+
+    /**
+     * Retrieve an optional array as a \SimpleSAML\Configuration object.
+     *
+     * This function will load the optional value of an option into a \SimpleSAML\Configuration object.
+     *   The option must contain an array.
+     *
+     * An exception will be thrown if this option isn't an array, or if this option isn't found.
+     *
+     * @param string     $name The name of the option.
      * @param array|null $default A default value which will be used if the option isn't found. An empty Configuration
-     *                        object will be returned if this parameter isn't given and the option doesn't exist.
-     *                        This function will only return null if $default is set to null and the option
-     *                        doesn't exist.
+     *                     object will be returned if this parameter isn't given and the option doesn't exist.
+     *                     This function will only return null if $default is set to null and the option doesn't exist.
      *
      * @return \SimpleSAML\Configuration|null The option with the given name,
-     *   or $default if the option isn't found and $default is specified.
+     *   or $default, converted into a Configuration object.
      *
-     * @throws \Exception If the option is not an array.
+     * @throws \SimpleSAML\Assert\AssertionFailed\Exception If the option is not an array.
      */
-    public function getConfigItem(string $name, $default = []): ?Configuration
+    public function getOptionalConfigItem(string $name, ?array $default): ?Configuration
     {
-        $ret = $this->getValue($name, $default);
-
-        if ($ret === null) {
-            // the option wasn't found, or it is explicitly null
-            // do not instantiate a new Configuration instance, but just return null
-            return null;
-        }
-
-        if (!is_array($ret)) {
-            throw new \Exception(
-                $this->location . ': The option ' . var_export($name, true) .
-                ' is not an array.'
-            );
+        if (!$this->hasValue($name)) {
+            // the option wasn't found, or it matches the default value. In any case, return this value
+            return $default;
         }
 
-        return self::loadFromArray($ret, $this->location . '[' . var_export($name, true) . ']');
+        return $this->getConfigItem($name);
     }
 
 
diff --git a/lib/SimpleSAML/Module.php b/lib/SimpleSAML/Module.php
index cc3c132cc67ad61c1f43d8bf1bdeb24a10b974ff..d956eaeb0e39c2b1345d45f2f7127ee22fba3d2e 100644
--- a/lib/SimpleSAML/Module.php
+++ b/lib/SimpleSAML/Module.php
@@ -299,9 +299,9 @@ class Module
         }
 
         /** @psalm-var \SimpleSAML\Configuration $assetConfig */
-        $assetConfig = $config->getConfigItem('assets');
+        $assetConfig = $config->getOptionalConfigItem('assets', null);
         /** @psalm-var \SimpleSAML\Configuration $cacheConfig */
-        $cacheConfig = $assetConfig->getConfigItem('caching');
+        $cacheConfig = $assetConfig ?: $assetOptionalConfig->getConfigItem('caching', null);
         $response = new BinaryFileResponse($path);
         $response->setCache([
             // "public" allows response caching even if the request was authenticated,
diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php
index 0bd1e351f6f38a56a9a8d9f1a4b95789830cbb59..25317d1c4b422f81a7ffed27d4809ed985dd0776 100644
--- a/lib/SimpleSAML/Utils/HTTP.php
+++ b/lib/SimpleSAML/Utils/HTTP.php
@@ -804,8 +804,8 @@ class HTTP
              */
 
             /** @var \SimpleSAML\Configuration $appcfg */
-            $appcfg = $cfg->getConfigItem('application');
-            $appurl = $appcfg->getOptionalString('baseURL', null);
+            $appcfg = $cfg->getOptionalConfigItem('application', null);
+            $appurl = $appcfg ?: $appcfg->getOptionalString('baseURL', null);
             if (!empty($appurl)) {
                 $protocol = parse_url($appurl, PHP_URL_SCHEME);
                 $hostname = parse_url($appurl, PHP_URL_HOST);
diff --git a/tests/lib/SimpleSAML/ConfigurationTest.php b/tests/lib/SimpleSAML/ConfigurationTest.php
index 3a6f1aeda0318ef1f98f8b91a4f545c8772497f5..b13e0782333113758ff239a0874eca021334d17e 100644
--- a/tests/lib/SimpleSAML/ConfigurationTest.php
+++ b/tests/lib/SimpleSAML/ConfigurationTest.php
@@ -647,25 +647,30 @@ class ConfigurationTest extends ClearStateTestCase
         $c = Configuration::loadFromArray([
             'opt' => ['a' => 42],
         ]);
-        $this->assertNull($c->getConfigItem('missing_opt', null));
+
         $opt = $c->getConfigItem('opt');
-        $notOpt = $c->getConfigItem('notOpt');
         $this->assertInstanceOf(Configuration::class, $opt);
-        $this->assertInstanceOf(Configuration::class, $notOpt);
-        $this->assertEquals($opt->getValue('a'), 42);
+
+        // Missing option
+        $this->expectException(AssertionFailedException::class);
+        $c->getConfigItem('missing_opt');
     }
 
 
     /**
-     * Test \SimpleSAML\Configuration::getConfigItem() wrong option
+     * Test \SimpleSAML\Configuration::getOptionalConfigItem()
      */
-    public function testGetConfigItemWrong(): void
+    public function testGetOptionalConfigItem(): void
     {
-        $this->expectException(Exception::class);
         $c = Configuration::loadFromArray([
-            'opt' => 'not_an_array',
+            'opt' => ['a' => 42],
         ]);
-        $c->getConfigItem('opt');
+
+        $opt = $c->getOptionalConfigItem('opt', null);
+        $this->assertInstanceOf(Configuration::class, $opt);
+
+        // Missing option
+        $this->assertNull($c->getOptionalConfigItem('missing_opt', null));
     }