diff --git a/src/mfm/language.ts b/src/mfm/language.ts
index bfa22e8c3b..4750ea3380 100644
--- a/src/mfm/language.ts
+++ b/src/mfm/language.ts
@@ -164,8 +164,10 @@ export const mfmLanguage = P.createLanguage({
 			} else
 				url = match[0];
 			url = removeOrphanedBrackets(url);
-			if (url.endsWith('.')) url = url.substr(0, url.lastIndexOf('.'));
-			if (url.endsWith(',')) url = url.substr(0, url.lastIndexOf(','));
+			while (url.endsWith('.') || url.endsWith(',')) {
+				if (url.endsWith('.')) url = url.substr(0, url.lastIndexOf('.'));
+				if (url.endsWith(',')) url = url.substr(0, url.lastIndexOf(','));
+			}
 			return P.makeSuccess(i + url.length, url);
 		}).map(x => createLeaf('url', { url: x }));
 	},
diff --git a/test/mfm.ts b/test/mfm.ts
index c772a62dcb..be8b65264a 100644
--- a/test/mfm.ts
+++ b/test/mfm.ts
@@ -804,6 +804,14 @@ describe('MFM', () => {
 				]);
 			});
 
+			it('ignore trailing periods', () => {
+				const tokens = parse('https://example.com...');
+				assert.deepStrictEqual(tokens, [
+					leaf('url', { url: 'https://example.com' }),
+					text('...')
+				]);
+			});
+
 			it('with comma', () => {
 				const tokens = parse('https://example.com/foo?bar=a,b');
 				assert.deepStrictEqual(tokens, [