diff --git a/UPGRADE_NOTES.md b/UPGRADE_NOTES.md
index 8bebd4eb34790dffea739fde66b1daa7864116c8..c941de6643d54bda49136dec6876e5188b0a3894 100644
--- a/UPGRADE_NOTES.md
+++ b/UPGRADE_NOTES.md
@@ -1,5 +1,38 @@
 # Upgrade Notes
 
+## 2024.10.0
+
+### Hellspawns
+
+Sharkey versions before 2024.10 suffered from a bug in the "Mark instance as NSFW" feature.
+When a user from such an instance boosted a note, the boost would be converted to a hellspawn (pure renote with Content Warning).
+Hellspawns are buggy and do not properly federate, so it may be desirable to correct any that already exist in the database.
+The following script will correct any local or remote hellspawns in the database.
+
+```postgresql
+/* Remove "instance is marked as NSFW" hellspawns */
+UPDATE "note"
+SET "cw" = null
+WHERE
+	"renoteId" IS NOT NULL
+	AND "text" IS NULL
+	AND "cw" = 'Instance is marked as NSFW'
+	AND "replyId" IS NULL
+	AND "hasPoll" = false
+	AND "fileIds" = '{}';
+
+/* Fix legacy / user-created hellspawns */
+UPDATE "note"
+SET "text" = '.'
+WHERE
+	"renoteId" IS NOT NULL
+	AND "text" IS NULL
+	AND "cw" IS NOT NULL
+	AND "replyId" IS NULL
+	AND "hasPoll" = false
+	AND "fileIds" = '{}';
+```
+
 ## 2024.9.0
 
 ### Following Feed
diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
index 1bc4599a602200a1bede36d9381aed4e04400188..892a929c41549c8a6a432148a1b30e3b4c0f6b77 100644
--- a/packages/backend/src/core/NoteCreateService.ts
+++ b/packages/backend/src/core/NoteCreateService.ts
@@ -146,6 +146,8 @@ type Option = {
 	app?: MiApp | null;
 };
 
+export type PureRenoteOption = Option & { renote: MiNote } & ({ text?: null } | { cw?: null } | { reply?: null } | { poll?: null } | { files?: null | [] });
+
 @Injectable()
 export class NoteCreateService implements OnApplicationShutdown {
 	#shutdownController = new AbortController();
@@ -412,7 +414,7 @@ export class NoteCreateService implements OnApplicationShutdown {
 
 		if (user.host && !data.cw) {
 			await this.federatedInstanceService.fetch(user.host).then(async i => {
-				if (i.isNSFW) {
+				if (i.isNSFW && !this.isPureRenote(data)) {
 					data.cw = 'Instance is marked as NSFW';
 				}
 			});
@@ -821,6 +823,11 @@ export class NoteCreateService implements OnApplicationShutdown {
 		if (!user.noindex) this.index(note);
 	}
 
+	@bindThis
+	public isPureRenote(note: Option): note is PureRenoteOption {
+		return this.isRenote(note) && !this.isQuote(note);
+	}
+
 	@bindThis
 	private isRenote(note: Option): note is Option & { renote: MiNote } {
 		return note.renote != null;
diff --git a/packages/backend/src/core/NoteEditService.ts b/packages/backend/src/core/NoteEditService.ts
index d31958e5d4abd3ac2ce5757d2e5b94377b94d009..e5e3c38cd3f057cd1d2a1175cd9b20d4ea46ab61 100644
--- a/packages/backend/src/core/NoteEditService.ts
+++ b/packages/backend/src/core/NoteEditService.ts
@@ -442,7 +442,7 @@ export class NoteEditService implements OnApplicationShutdown {
 
 		if (user.host && !data.cw) {
 			await this.federatedInstanceService.fetch(user.host).then(async i => {
-				if (i.isNSFW) {
+				if (i.isNSFW && !this.noteCreateService.isPureRenote(data)) {
 					data.cw = 'Instance is marked as NSFW';
 				}
 			});