diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py
index 4d6d8b9008..6b69a3c7ef 100644
--- a/django/core/urlresolvers.py
+++ b/django/core/urlresolvers.py
@@ -549,19 +549,26 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
         view = parts[0]
         path = parts[1:]
 
+        if current_app:
+            current_path = current_app.split(':')
+            current_path.reverse()
+        else:
+            current_path = None
+
         resolved_path = []
         ns_pattern = ''
         while path:
             ns = path.pop()
+            current_ns = current_path.pop() if current_path else None
 
             # Lookup the name to see if it could be an app identifier
             try:
                 app_list = resolver.app_dict[ns]
                 # Yes! Path part matches an app in the current Resolver
-                if current_app and current_app in app_list:
+                if current_ns and current_ns in app_list:
                     # If we are reversing for a particular app,
                     # use that namespace
-                    ns = current_app
+                    ns = current_ns
                 elif ns not in app_list:
                     # The name isn't shared by one of the instances
                     # (i.e., the default) so just pick the first instance
@@ -570,6 +577,9 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
             except KeyError:
                 pass
 
+            if ns != current_ns:
+                current_path = None
+
             try:
                 extra, resolver = resolver.namespace_dict[ns]
                 resolved_path.append(ns)
diff --git a/tests/urlpatterns_reverse/included_namespace_urls.py b/tests/urlpatterns_reverse/included_namespace_urls.py
index 8769f112e9..43bba1b6de 100644
--- a/tests/urlpatterns_reverse/included_namespace_urls.py
+++ b/tests/urlpatterns_reverse/included_namespace_urls.py
@@ -7,6 +7,7 @@ from .namespace_urls import URLObject
 from .views import view_class_instance
 
 testobj3 = URLObject('testapp', 'test-ns3')
+testobj4 = URLObject('testapp', 'test-ns4')
 
 # test deprecated patterns() function. convert to list of urls() in Django 2.0
 with warnings.catch_warnings():
@@ -24,6 +25,7 @@ with warnings.catch_warnings():
         url(r'^view_class/(?P<arg1>[0-9]+)/(?P<arg2>[0-9]+)/$', view_class_instance, name='inc-view-class'),
 
         (r'^test3/', include(testobj3.urls)),
+        (r'^test4/', include(testobj4.urls)),
         (r'^ns-included3/', include('urlpatterns_reverse.included_urls', namespace='inc-ns3')),
         (r'^ns-included4/', include('urlpatterns_reverse.namespace_urls', namespace='inc-ns4')),
     )
diff --git a/tests/urlpatterns_reverse/tests.py b/tests/urlpatterns_reverse/tests.py
index f863a089d4..f2137da6ad 100644
--- a/tests/urlpatterns_reverse/tests.py
+++ b/tests/urlpatterns_reverse/tests.py
@@ -574,6 +574,53 @@ class NamespaceTests(SimpleTestCase):
         self.assertEqual('/inc70/', reverse('inc-ns5:inner-nothing', args=['70']))
         self.assertEqual('/inc78/extra/foobar/', reverse('inc-ns5:inner-extra', args=['78', 'foobar']))
 
+    def test_nested_app_lookup(self):
+        "A nested current_app should be split in individual namespaces (#24904)"
+        self.assertEqual('/ns-included1/test4/inner/', reverse('inc-ns1:testapp:urlobject-view'))
+        self.assertEqual('/ns-included1/test4/inner/37/42/', reverse('inc-ns1:testapp:urlobject-view', args=[37, 42]))
+        self.assertEqual(
+            '/ns-included1/test4/inner/42/37/',
+            reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37})
+        )
+        self.assertEqual('/ns-included1/test4/inner/+%5C$*/', reverse('inc-ns1:testapp:urlobject-special-view'))
+
+        self.assertEqual(
+            '/ns-included1/test3/inner/',
+            reverse('inc-ns1:testapp:urlobject-view', current_app='inc-ns1:test-ns3')
+        )
+        self.assertEqual(
+            '/ns-included1/test3/inner/37/42/',
+            reverse('inc-ns1:testapp:urlobject-view', args=[37, 42], current_app='inc-ns1:test-ns3')
+        )
+        self.assertEqual(
+            '/ns-included1/test3/inner/42/37/',
+            reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37}, current_app='inc-ns1:test-ns3')
+        )
+        self.assertEqual(
+            '/ns-included1/test3/inner/+%5C$*/',
+            reverse('inc-ns1:testapp:urlobject-special-view', current_app='inc-ns1:test-ns3')
+        )
+
+    def test_current_app_no_partial_match(self):
+        "current_app should either match the whole path or shouldn't be used"
+        self.assertEqual(
+            '/ns-included1/test4/inner/',
+            reverse('inc-ns1:testapp:urlobject-view', current_app='non-existant:test-ns3')
+        )
+        self.assertEqual(
+            '/ns-included1/test4/inner/37/42/',
+            reverse('inc-ns1:testapp:urlobject-view', args=[37, 42], current_app='non-existant:test-ns3')
+        )
+        self.assertEqual(
+            '/ns-included1/test4/inner/42/37/',
+            reverse('inc-ns1:testapp:urlobject-view', kwargs={'arg1': 42, 'arg2': 37},
+                    current_app='non-existant:test-ns3')
+        )
+        self.assertEqual(
+            '/ns-included1/test4/inner/+%5C$*/',
+            reverse('inc-ns1:testapp:urlobject-special-view', current_app='non-existant:test-ns3')
+        )
+
 
 @override_settings(ROOT_URLCONF=urlconf_outer.__name__)
 class RequestURLconfTests(SimpleTestCase):