diff --git a/addons/mail/static/src/utils/common/format.js b/addons/mail/static/src/utils/common/format.js
index 93d458e13c0..cc208da6cac 100644
--- a/addons/mail/static/src/utils/common/format.js
+++ b/addons/mail/static/src/utils/common/format.js
@@ -107,7 +107,8 @@ function linkify(text) {
let match;
while ((match = urlRegexp.exec(text)) !== null) {
result += _escapeEntities(text.slice(curIndex, match.index));
- const url = match[0];
+ // Decode the url first, in case it's already an encoded url
+ const url = decodeURI(match[0]);
const href = encodeURI(!/^https?:\/\//i.test(url) ? "http://" + url : url);
result += `${_escapeEntities(
url
diff --git a/addons/mail/static/tests/mail_utils_tests.js b/addons/mail/static/tests/mail_utils_tests.js
index b397f01e694..c833c522d73 100644
--- a/addons/mail/static/tests/mail_utils_tests.js
+++ b/addons/mail/static/tests/mail_utils_tests.js
@@ -52,6 +52,8 @@ QUnit.test("addLink: utility function and special entities", function (assert) {
":'(": ":'(",
// special character in smileys should be escaped
"<3": "<3",
+ // Already encoded url should not be encoded twice
+ "https://odoo.com/%5B%5D": `https://odoo.com/[]`,
};
for (const [content, result] of Object.entries(testInputs)) {