diff --git a/.gitignore b/.gitignore
index a4e031399..d511fa5ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,3 +59,8 @@ packages/backend/assets/instance.css
 *.blend3
 *.blend4
 *.blend5
+
+#intelij stuff
+packages/backend/.idea/backend.iml
+packages/backend/.idea/modules.xml
+packages/backend/.idea/vcs.xml
diff --git a/locales/de-DE.yml b/locales/de-DE.yml
index d7920b361..ea0fb8846 100644
--- a/locales/de-DE.yml
+++ b/locales/de-DE.yml
@@ -112,6 +112,7 @@ reactionSettingDescription2: "Ziehe um Anzuordnen, klicke um zu löschen, drück
 rememberNoteVisibility: "Notizsichtbarkeit merken"
 attachCancel: "Anhang entfernen"
 markAsSensitive: "Als NSFW markieren"
+accountMoved: "Benutzer hat zu einem anderen Account gewechselt."
 unmarkAsSensitive: "Als nicht NSFW markieren"
 enterFileName: "Dateinamen eingeben"
 mute: "Stummschalten"
diff --git a/locales/en-US.yml b/locales/en-US.yml
index f5758ed64..1215055d5 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -149,6 +149,7 @@ addAccount: "Add account"
 loginFailed: "Failed to sign in"
 showOnRemote: "View on remote instance"
 general: "General"
+accountMoved: "User has moved to a new account."
 wallpaper: "Wallpaper"
 setWallpaper: "Set wallpaper"
 removeWallpaper: "Remove wallpaper"
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index b045f5448..90820d43a 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -149,6 +149,7 @@ addAccount: "アカウントを追加"
 loginFailed: "ログインに失敗しました"
 showOnRemote: "リモートで表示"
 general: "全般"
+accountMoved: "このユーザーは新しいアカウントに移行しました"
 wallpaper: "壁紙"
 setWallpaper: "壁紙を設定"
 removeWallpaper: "壁紙を削除"
diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts
index 5c46ae27a..47ab1fc9e 100644
--- a/packages/backend/src/models/repositories/user.ts
+++ b/packages/backend/src/models/repositories/user.ts
@@ -1,16 +1,38 @@
-import { EntityRepository, Repository, In, Not } from 'typeorm';
+import {In, Not} from 'typeorm';
 import Ajv from 'ajv';
-import { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js';
+import {ILocalUser, IRemoteUser, User} from '@/models/entities/user.js';
 import config from '@/config/index.js';
-import { Packed } from '@/misc/schema.js';
-import { awaitAll, Promiseable } from '@/prelude/await-all.js';
-import { populateEmojis } from '@/misc/populate-emojis.js';
-import { getAntennas } from '@/misc/antenna-cache.js';
-import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js';
-import { Cache } from '@/misc/cache.js';
-import { db } from '@/db/postgre.js';
-import { Instance } from '../entities/instance.js';
-import { Notes, NoteUnreads, FollowRequests, Notifications, MessagingMessages, UserNotePinings, Followings, Blockings, Mutings, UserProfiles, UserSecurityKeys, UserGroupJoinings, Pages, Announcements, AnnouncementReads, Antennas, AntennaNotes, ChannelFollowings, Instances, DriveFiles } from '../index.js';
+import {Packed} from '@/misc/schema.js';
+import {awaitAll, Promiseable} from '@/prelude/await-all.js';
+import {populateEmojis} from '@/misc/populate-emojis.js';
+import {getAntennas} from '@/misc/antenna-cache.js';
+import {USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD} from '@/const.js';
+import {Cache} from '@/misc/cache.js';
+import {db} from '@/db/postgre.js';
+import {Instance} from '../entities/instance.js';
+import {resolveUser} from "@/remote/resolve-user";
+import {URL} from "url";
+import {
+	AnnouncementReads,
+	Announcements,
+	AntennaNotes,
+	Blockings,
+	ChannelFollowings,
+	DriveFiles,
+	Followings,
+	FollowRequests,
+	Instances,
+	MessagingMessages,
+	Mutings,
+	Notes,
+	NoteUnreads,
+	Notifications,
+	Pages,
+	UserGroupJoinings,
+	UserNotePinings,
+	UserProfiles,
+	UserSecurityKeys
+} from '../index.js';
 
 const userInstanceCache = new Cache<Instance | null>(1000 * 60 * 60 * 3);
 
@@ -156,6 +178,23 @@ export const UserRepository = db.getRepository(User).extend({
 		return count > 0;
 	},
 
+	async userFromURI(uri: string): Promise<User | null> {
+		if (uri.startsWith(config.url + '/')) {
+			const id = uri.split('/').pop();
+			if (id == undefined) return null;
+			return await resolveUser(id, null);
+		}
+
+		let url = new URL(uri);
+		let userTag = url.pathname;
+
+		if (userTag.startsWith("@")) {
+			userTag = userTag.substring(1);
+		}
+
+		return await resolveUser(userTag, url.host);
+	},
+
 	async getHasUnreadAntenna(userId: User['id']): Promise<boolean> {
 		const myAntennas = (await getAntennas()).filter(a => a.userId === userId);
 
@@ -320,6 +359,8 @@ export const UserRepository = db.getRepository(User).extend({
 			...(opts.detail ? {
 				url: profile!.url,
 				uri: user.uri,
+				movedTo: user.movedToUri ? await this.userFromURI(user.movedToUri) : null,
+				alsoKnownAs: user.alsoKnownAs,
 				createdAt: user.createdAt.toISOString(),
 				updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null,
 				lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null,
diff --git a/packages/backend/src/models/schema/user.ts b/packages/backend/src/models/schema/user.ts
index 218d861e5..95827272f 100644
--- a/packages/backend/src/models/schema/user.ts
+++ b/packages/backend/src/models/schema/user.ts
@@ -96,6 +96,16 @@ export const packedUserDetailedNotMeOnlySchema = {
 			format: 'uri',
 			nullable: true, optional: false,
 		},
+		movedTo: {
+			type: 'string',
+			format: 'uri',
+			nullable: true, optional: false,
+		},
+		alsoKnownAs: {
+			type: 'array',
+			format: 'uri',
+			nullable: true, optional: false,
+		},
 		createdAt: {
 			type: 'string',
 			nullable: false, optional: false,
diff --git a/packages/client/src/components/MkMoved.vue b/packages/client/src/components/MkMoved.vue
new file mode 100644
index 000000000..f5ec1a567
--- /dev/null
+++ b/packages/client/src/components/MkMoved.vue
@@ -0,0 +1,25 @@
+<template>
+<div class="mkmoved _block"><i class="fas fa-info-circle" style="margin-right: 8px;"></i>{{ i18n.ts.accountMoved }}<a class="link" :href="href">{{ acct }}</a></div>
+</template>
+
+<script lang="ts" setup>
+import { i18n } from '@/i18n';
+import { computed } from 'vue';
+const props = defineProps<{
+	acct: string;
+}>();
+const href = $computed(() => `/${props.acct}`);
+</script>
+
+<style lang="scss" scoped>
+.mkmoved {
+	font-size: 0.8em;
+	padding: 16px;
+	background: var(--infoBg);
+	color: var(--infoFg);
+	> .link {
+		margin-left: 4px;
+		color: var(--accent);
+	}
+}
+</style>
diff --git a/packages/client/src/pages/user/home.vue b/packages/client/src/pages/user/home.vue
index b0ff75eef..e8e111cae 100644
--- a/packages/client/src/pages/user/home.vue
+++ b/packages/client/src/pages/user/home.vue
@@ -8,6 +8,7 @@
 
 			<div class="profile">
 				<MkRemoteCaution v-if="user.host != null" :href="user.url" class="warn"/>
+				<MkMoved v-if="user.movedTo" :acct="user.movedTo" />
 
 				<div :key="user.id" class="_block main">
 					<div class="banner-container" :style="style">
@@ -119,6 +120,7 @@ import MkFolder from '@/components/MkFolder.vue';
 import MkRemoteCaution from '@/components/MkRemoteCaution.vue';
 import MkTab from '@/components/MkTab.vue';
 import MkInfo from '@/components/MkInfo.vue';
+import MkMoved from '@/components/MkMoved.vue';
 import { getScrollPosition } from '@/scripts/scroll';
 import { getUserMenu } from '@/scripts/get-user-menu';
 import number from '@/filters/number';