diff --git a/CHANGES b/CHANGES
index c3bd480da..c74a46588 100644
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,8 @@
 
 Version 8.0.27
 
+  - Fix for Bug#104641 (33237255), DatabaseMetaData.getImportedKeys can return duplicated foreign keys.
+
   - Fix for Bug#33185116, Have method ResultSet.getBoolean() supporting conversion of 'T' and 'F' in a VARCHAR to True/False (boolean).
 
   - Fix for Bug#31117686, PROTOCOL ALLOWLIST NOT COMPATIBLE WITH IBM JAVA.
diff --git a/src/main/user-impl/java/com/mysql/cj/jdbc/DatabaseMetaDataUsingInfoSchema.java b/src/main/user-impl/java/com/mysql/cj/jdbc/DatabaseMetaDataUsingInfoSchema.java
index 285c3f8fe..8f1d3e19f 100644
--- a/src/main/user-impl/java/com/mysql/cj/jdbc/DatabaseMetaDataUsingInfoSchema.java
+++ b/src/main/user-impl/java/com/mysql/cj/jdbc/DatabaseMetaDataUsingInfoSchema.java
@@ -453,14 +453,11 @@ public java.sql.ResultSet getImportedKeys(String catalog, String schema, String
         sqlBuf.append(generateUpdateRuleClause());
         sqlBuf.append(" AS UPDATE_RULE,");
         sqlBuf.append(generateDeleteRuleClause());
-        sqlBuf.append(" AS DELETE_RULE, A.CONSTRAINT_NAME AS FK_NAME, TC.CONSTRAINT_NAME AS PK_NAME,");
+        sqlBuf.append(" AS DELETE_RULE, A.CONSTRAINT_NAME AS FK_NAME, R.UNIQUE_CONSTRAINT_NAME AS PK_NAME,");
         sqlBuf.append(importedKeyNotDeferrable);
         sqlBuf.append(" AS DEFERRABILITY FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE A");
         sqlBuf.append(" JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS B USING (CONSTRAINT_NAME, TABLE_NAME) ");
         sqlBuf.append(generateOptionalRefContraintsJoin());
-        sqlBuf.append(" LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC ON (A.REFERENCED_TABLE_SCHEMA = TC.TABLE_SCHEMA");
-        sqlBuf.append("  AND A.REFERENCED_TABLE_NAME = TC.TABLE_NAME");
-        sqlBuf.append("  AND TC.CONSTRAINT_TYPE IN ('UNIQUE', 'PRIMARY KEY'))");
         sqlBuf.append("WHERE B.CONSTRAINT_TYPE = 'FOREIGN KEY'");
         if (db != null) {
             sqlBuf.append(" AND A.TABLE_SCHEMA = ?");
diff --git a/src/test/java/testsuite/regression/MetaDataRegressionTest.java b/src/test/java/testsuite/regression/MetaDataRegressionTest.java
index d3a84e79c..cd91af894 100644
--- a/src/test/java/testsuite/regression/MetaDataRegressionTest.java
+++ b/src/test/java/testsuite/regression/MetaDataRegressionTest.java
@@ -5314,4 +5314,81 @@ public void testBug95280() throws Exception {
             }
         }
     }
+
+    /**
+     * Tests fix for Bug#104641 (33237255), DatabaseMetaData.getImportedKeys can return duplicated foreign keys.
+     * 
+     * @throws Exception
+     */
+    @Test
+    public void testBug104641() throws Exception {
+        String databaseName1 = "dbBug104641";
+        createDatabase(databaseName1);
+        createTable(databaseName1 + ".table1",
+                "(`CREATED` datetime DEFAULT NULL,`ID` bigint NOT NULL AUTO_INCREMENT,`LRN_ID` bigint DEFAULT '0',`USERNAME` varchar(50) NOT NULL,"
+                        + "PRIMARY KEY (`ID`),UNIQUE KEY `U_table1_LRN_ID` (`LRN_ID`),UNIQUE KEY `U_table1_USERNAME` (`USERNAME`) )");
+        createTable(databaseName1 + ".table2",
+                "(`AL_ID` varchar(50) DEFAULT NULL,`CREATED` datetime DEFAULT NULL,`ID` bigint NOT NULL AUTO_INCREMENT,`USER_ID` bigint DEFAULT NULL,"
+                        + "PRIMARY KEY (`ID`),KEY `fk_table2_user_id` (`USER_ID`),KEY `index_al_id1` (`AL_ID`),"
+                        + "CONSTRAINT `fk_table2_user_id` FOREIGN KEY (`USER_ID`) REFERENCES `table1` (`ID`) )");
+        createTable(databaseName1 + ".table3",
+                "(`AL_ID` varchar(50) DEFAULT NULL,`ID` bigint NOT NULL AUTO_INCREMENT,`USER_ID` bigint DEFAULT NULL,`LRN_ID` bigint DEFAULT '0',"
+                        + "PRIMARY KEY (`ID`),KEY `fk_table3_LRN_ID` (`LRN_ID`),KEY `index_al_id2` (`AL_ID`),"
+                        + "CONSTRAINT `fk_table3_LRN_ID` FOREIGN KEY `U_table1_LRN_ID` (`LRN_ID`) REFERENCES `table1` (`LRN_ID`) )");
+
+        Properties props = new Properties();
+        props.setProperty(PropertyKey.useSSL.getKeyName(), "false");
+        props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
+        for (boolean useIS : new boolean[] { false, true }) {
+            for (String databaseTerm : new String[] { "CATALOG", "SCHEMA" }) {
+                props.setProperty(PropertyKey.useInformationSchema.getKeyName(), "" + useIS);
+                props.setProperty(PropertyKey.databaseTerm.getKeyName(), databaseTerm);
+
+                boolean dbTermIsSchema = databaseTerm.contentEquals("SCHEMA");
+
+                String err = "useInformationSchema=" + useIS + ", databaseTerm=" + databaseTerm;
+                Connection con = getConnectionWithProps(props);
+                DatabaseMetaData meta = con.getMetaData();
+
+                this.rs = dbTermIsSchema ? meta.getImportedKeys(null, databaseName1, "table2") : meta.getImportedKeys(databaseName1, null, "table2");
+                assertTrue(this.rs.next(), err);
+                assertEquals(dbTermIsSchema ? "def" : databaseName1, this.rs.getString("PKTABLE_CAT"), err);
+                assertEquals(dbTermIsSchema ? databaseName1 : null, this.rs.getString("PKTABLE_SCHEM"), err);
+                assertEquals(dbTermIsSchema ? "def" : databaseName1, this.rs.getString("FKTABLE_CAT"), err);
+                assertEquals(dbTermIsSchema ? databaseName1 : null, this.rs.getString("FKTABLE_SCHEM"), err);
+                assertEquals("table1", this.rs.getString("PKTABLE_NAME"), err);
+                assertEquals("ID", this.rs.getString("PKCOLUMN_NAME"), err);
+                assertEquals("table2", this.rs.getString("FKTABLE_NAME"), err);
+                assertEquals("USER_ID", this.rs.getString("FKCOLUMN_NAME"), err);
+                assertEquals(1, this.rs.getInt("KEY_SEQ"), err);
+                assertEquals(1, this.rs.getInt("UPDATE_RULE"), err);
+                assertEquals(1, this.rs.getInt("DELETE_RULE"), err);
+                assertEquals("fk_table2_user_id", this.rs.getString("FK_NAME"), err);
+                assertEquals(useIS ? "PRIMARY" : null, this.rs.getString("PK_NAME"), err);
+                assertEquals(7, this.rs.getInt("DEFERRABILITY"), err);
+                assertFalse(this.rs.next(), err);
+
+                this.rs = dbTermIsSchema ? meta.getImportedKeys(null, databaseName1, "table3") : meta.getImportedKeys(databaseName1, null, "table3");
+                assertTrue(this.rs.next(), err);
+                assertEquals(dbTermIsSchema ? "def" : databaseName1, this.rs.getString("PKTABLE_CAT"), err);
+                assertEquals(dbTermIsSchema ? databaseName1 : null, this.rs.getString("PKTABLE_SCHEM"), err);
+                assertEquals(dbTermIsSchema ? "def" : databaseName1, this.rs.getString("FKTABLE_CAT"), err);
+                assertEquals(dbTermIsSchema ? databaseName1 : null, this.rs.getString("FKTABLE_SCHEM"), err);
+                assertEquals("table1", this.rs.getString("PKTABLE_NAME"), err);
+                assertEquals("LRN_ID", this.rs.getString("PKCOLUMN_NAME"), err);
+                assertEquals("table3", this.rs.getString("FKTABLE_NAME"), err);
+                assertEquals("LRN_ID", this.rs.getString("FKCOLUMN_NAME"), err);
+                assertEquals(1, this.rs.getInt("KEY_SEQ"), err);
+                assertEquals(1, this.rs.getInt("UPDATE_RULE"), err);
+                assertEquals(1, this.rs.getInt("DELETE_RULE"), err);
+                assertEquals("fk_table3_LRN_ID", this.rs.getString("FK_NAME"), err);
+                assertEquals(useIS ? "U_table1_LRN_ID" : null, this.rs.getString("PK_NAME"), err);
+                assertEquals(7, this.rs.getInt("DEFERRABILITY"), err);
+                assertFalse(this.rs.next(), err);
+
+                con.close();
+            }
+        }
+
+    }
 }