diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py
index fcc3a21c97a9cc453f6ea0e860685fe319091cad..792ab2aef2f89aa5d1fd6afca93021b18361ffc2 100644
--- a/Cython/Compiler/PyrexTypes.py
+++ b/Cython/Compiler/PyrexTypes.py
@@ -2553,11 +2553,11 @@ class CFuncType(CType):
     def as_argument_type(self):
         return c_ptr_type(self)
 
-    def same_c_signature_as(self, other_type, as_cmethod = 0):
+    def same_c_signature_as(self, other_type, as_cmethod = 0, as_pxd_definition = 0):
         return self.same_c_signature_as_resolved_type(
             other_type.resolve(), as_cmethod)
 
-    def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
+    def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0, as_pxd_definition = 0):
         #print "CFuncType.same_c_signature_as_resolved_type:", \
         #    self, other_type, "as_cmethod =", as_cmethod ###
         if other_type is error_type:
@@ -2579,8 +2579,13 @@ class CFuncType(CType):
             return 0
         if self.optional_arg_count != other_type.optional_arg_count:
             return 0
-        if not self.return_type.same_as(other_type.return_type):
-            return 0
+        if as_pxd_definition:
+            # A narrowing of the return type declared in the pxd is allowed.
+            if not self.return_type.subtype_of_resolved_type(other_type.return_type):
+                return 0
+        else:
+            if not self.return_type.same_as(other_type.return_type):
+                return 0
         if not self.same_calling_convention_as(other_type):
             return 0
         if self.exception_check != other_type.exception_check:
diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py
index d42f7f624b50f6e68cdf658a88ccbf091720579b..99d256d875d251dbdf99bb2419eb36cd34c117d6 100644
--- a/Cython/Compiler/Symtab.py
+++ b/Cython/Compiler/Symtab.py
@@ -2094,7 +2094,8 @@ class CClassScope(ClassScope):
                     # Fix with_gil vs nogil.
                     entry.type = entry.type.with_with_gil(type.with_gil)
                 elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
-                    if self.defined and not in_pxd:
+                    if (self.defined and not in_pxd
+                        and not type.same_c_signature_as_resolved_type(entry.type, as_cmethod = 1, as_pxd_definition = 1)):
                         error(pos,
                             "Compatible but non-identical C method '%s' not redeclared "
                             "in definition part of extension type '%s'" % (name, self.class_name))
diff --git a/tests/errors/cmethbasematch.pxd b/tests/errors/cmethbasematch.pxd
index 24e5466be26d97ebeba5989a7b353476c9fd29af..dc4aa2762097570fd293f4adf4336edb74b1369b 100644
--- a/tests/errors/cmethbasematch.pxd
+++ b/tests/errors/cmethbasematch.pxd
@@ -6,3 +6,6 @@ cdef class MissingRedeclaration(Base):
 
 cdef class BadRedeclaration(Base):
   cdef f(self)
+
+cdef class NarrowerReturn(Base):
+  pass
diff --git a/tests/errors/cmethbasematch.pyx b/tests/errors/cmethbasematch.pyx
index 1c1488a182c5949bd0ee790ff8d645e2ca230a14..154946ab9842d688dc1370f63234377aa2ff8a7a 100644
--- a/tests/errors/cmethbasematch.pyx
+++ b/tests/errors/cmethbasematch.pyx
@@ -28,6 +28,11 @@ cdef class UnneededRedeclaration(Base):
   cpdef f(self):
     pass
 
+cdef class NarrowerReturn(Base):
+  # This does not require a new vtable entry.
+  cdef Base f(self):
+    pass
+
 
 _ERRORS = u"""
 8: 9: Signature not compatible with previous declaration