diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 2efe50f5f30..db3ab656798 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -2708,6 +2708,7 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
 void CSharpScript::_clear() {
 	tool = false;
 	valid = false;
+	reload_invalidated = true;
 
 	base = NULL;
 	native = NULL;
@@ -2811,6 +2812,7 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon
 
 	p_script->valid = true;
 	p_script->tool = p_script->script_class->has_attribute(CACHED_CLASS(ToolAttribute));
+	p_script->reload_invalidated = false;
 
 	if (!p_script->tool) {
 		GDMonoClass *nesting_class = p_script->script_class->get_nesting_class();
@@ -3117,13 +3119,12 @@ MethodInfo CSharpScript::get_method_info(const StringName &p_method) const {
 }
 
 Error CSharpScript::reload(bool p_keep_state) {
-	bool has_instances;
-	{
-		MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
-		has_instances = instances.size();
+	if (!reload_invalidated) {
+		return OK;
 	}
-
-	ERR_FAIL_COND_V(!p_keep_state && has_instances, ERR_ALREADY_IN_USE);
+	// In the case of C#, reload doesn't really do any script reloading.
+	// That's done separately via domain reloading.
+	reload_invalidated = false;
 
 	GD_MONO_SCOPE_THREAD_ATTACH;
 
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 68eeb642161..e6c1073d69e 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -74,6 +74,7 @@ class CSharpScript : public Script {
 
 	bool tool;
 	bool valid;
+	bool reload_invalidated;
 
 	bool builtin;