diff --git a/docs/simplesamlphp-reference-idp-hosted.md b/docs/simplesamlphp-reference-idp-hosted.md
index 122814f7e52ac7551c4ca1a0f96b8f6b4c5569c2..2730c1178356b3403726114acc1c736541ac75d5 100644
--- a/docs/simplesamlphp-reference-idp-hosted.md
+++ b/docs/simplesamlphp-reference-idp-hosted.md
@@ -381,6 +381,10 @@ See the documentation for those extensions for more details:
   * [MDRPI extension](./simplesamlphp-metadata-extensions-rpi)
   * [EntityAttributes](./simplesamlphp-metadata-extensions-attributes)
 
+For other metadata extensions, you can use the `saml:Extensions` option:
+
+`saml:Extensions`
+:   An array of `\SAML2\XML\Chunk`s to include in the IdP metadata extensions, at the same level as `EntityAttributes`.
 
 Examples
 --------
@@ -411,3 +415,40 @@ These are some examples of IdP metadata
          */
         'auth' => 'example-userpass',
     ];
+
+### A custom metadata extension (eduGAIN republish request) ###
+
+```
+<?php
+
+$dom = \SAML2\DOMDocumentFactory::create();
+$republishRequest = $dom->createElementNS('http://eduid.cz/schema/metadata/1.0', 'eduidmd:RepublishRequest');
+$republishTarget = $dom->createElementNS('http://eduid.cz/schema/metadata/1.0', 'eduidmd:RepublishTarget', 'http://edugain.org/');
+$republishRequest->appendChild($republishTarget);
+$ext = [new \SAML2\XML\Chunk($republishRequest)];
+
+$metadata['__DYNAMIC:1__'] = [
+    'host' => '__DEFAULT__',
+    'certificate' => 'example.org.crt',
+    'privatekey' => 'example.org.pem',
+    'auth' => 'example-userpass',
+
+    /*
+     * The custom metadata extensions.
+     */
+    'saml:Extensions' => $ext,
+];
+```
+
+this generates the following metadata:
+
+```
+<EntityDescriptor entityID="...">
+  <Extensions xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
+    <eduidmd:RepublishRequest xmlns:eduidmd="http://eduid.cz/schema/metadata/1.0">
+      <eduidmd:RepublishTarget>http://edugain.org/</eduidmd:RepublishTarget>
+    </eduidmd:RepublishRequest>
+  </Extensions>
+  <!-- rest of metadata -->
+</EntityDescriptor>
+```
diff --git a/lib/SimpleSAML/Metadata/SAMLBuilder.php b/lib/SimpleSAML/Metadata/SAMLBuilder.php
index 47d873405f9b1d9dc67e9d3b9a19fb1fdf964a7e..a41931cce655cfa61bb7ce8df54abd35ca026fb8 100644
--- a/lib/SimpleSAML/Metadata/SAMLBuilder.php
+++ b/lib/SimpleSAML/Metadata/SAMLBuilder.php
@@ -225,6 +225,12 @@ class SAMLBuilder
             );
         }
 
+        if ($metadata->hasValue('saml:Extensions')) {
+            $this->entityDescriptor->setExtensions(
+                array_merge($this->entityDescriptor->getExtensions(), $metadata->getArray('saml:Extensions'))
+            );
+        }
+
         if ($metadata->hasValue('RegistrationInfo')) {
             $ri = new RegistrationInfo();
             foreach ($metadata->getArray('RegistrationInfo') as $riName => $riValues) {
diff --git a/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php b/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php
index 2998a753a8d49a0dd102b3c4d57ca300edbf90bd..42e254619dffbfaee1724750effa8be53e487189 100644
--- a/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php
+++ b/tests/lib/SimpleSAML/Metadata/SAMLBuilderTest.php
@@ -240,4 +240,44 @@ class SAMLBuilderTest extends TestCase
             $entityDescriptorXml
         );
     }
+
+    /**
+     * Test custom metadata extension (saml:Extensions).
+     */
+    public function testCustomMetadataExtension(): void
+    {
+        $entityId = 'https://entity.example.com/id';
+        $set = 'saml20-idp-remote';
+
+        $dom = \SAML2\DOMDocumentFactory::create();
+        $republishRequest = $dom->createElementNS(
+            'http://eduid.cz/schema/metadata/1.0',
+            'eduidmd:RepublishRequest'
+        );
+        $republishTargetContent = 'http://edugain.org/';
+        $republishTarget = $dom->createElementNS(
+            'http://eduid.cz/schema/metadata/1.0',
+            'eduidmd:RepublishTarget',
+            $republishTargetContent
+        );
+        $republishRequest->appendChild($republishTarget);
+        $ext = [new \SAML2\XML\Chunk($republishRequest)];
+
+        $metadata = [
+            'entityid' => $entityId,
+            'name' => ['en' => 'Test IdP'],
+            'metadata-set' => $set,
+            'saml:Extensions' => $ext,
+        ];
+
+        $samlBuilder = new SAMLBuilder($entityId);
+        $samlBuilder->addMetadata($set, $metadata);
+
+        $idpDesc = $samlBuilder->getEntityDescriptor();
+        $rt = $idpDesc->getElementsByTagNameNS('http://eduid.cz/schema/metadata/1.0', 'RepublishTarget');
+
+        /** @var \DOMElement $rt1 */
+        $rt1 = $rt->item(0);
+        $this->assertEquals($republishTargetContent, $rt1->textContent);
+    }
 }
diff --git a/www/saml2/idp/metadata.php b/www/saml2/idp/metadata.php
index 2f6807e8ecf6d5d66722c58367c0215e949b0dcd..68404390f2b213293753c5cb7c0d1e3e415aad23 100644
--- a/www/saml2/idp/metadata.php
+++ b/www/saml2/idp/metadata.php
@@ -173,6 +173,10 @@ try {
         }
     }
 
+    if ($idpmeta->hasValue('saml:Extensions')) {
+        $metaArray['saml:Extensions'] = $idpmeta->getArray('saml:Extensions');
+    }
+
     if ($idpmeta->hasValue('UIInfo')) {
         $metaArray['UIInfo'] = $idpmeta->getArray('UIInfo');
     }