diff --git a/sys/net/application_layer/gcoap/gcoap.c b/sys/net/application_layer/gcoap/gcoap.c
index 2487c44d5c3409bd8f006ab9c8294d229101d521..c3c6e1105c1992534b10db15f6c45bcf5199f0f1 100644
--- a/sys/net/application_layer/gcoap/gcoap.c
+++ b/sys/net/application_layer/gcoap/gcoap.c
@@ -30,6 +30,11 @@
 #define ENABLE_DEBUG (0)
 #include "debug.h"
 
+/* Return values used by the _find_resource function. */
+#define GCOAP_RESOURCE_FOUND 0
+#define GCOAP_RESOURCE_WRONG_METHOD -1
+#define GCOAP_RESOURCE_NO_PATH -2
+
 /* Internal functions */
 static void *_event_loop(void *arg);
 static void _listen(sock_udp_t *sock);
@@ -42,7 +47,7 @@ static void _expire_request(gcoap_request_memo_t *memo);
 static bool _endpoints_equal(const sock_udp_ep_t *ep1, const sock_udp_ep_t *ep2);
 static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *pdu,
                            const sock_udp_ep_t *remote);
-static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
+static int _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
                                             gcoap_listener_t **listener_ptr);
 static int _find_observer(sock_udp_ep_t **observer, sock_udp_ep_t *remote);
 static int _find_obs_memo(gcoap_observe_memo_t **memo, sock_udp_ep_t *remote,
@@ -260,19 +265,21 @@ static void _listen(sock_udp_t *sock)
 static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
                                                          sock_udp_ep_t *remote)
 {
-    coap_resource_t *resource;
-    gcoap_listener_t *listener;
+    coap_resource_t *resource  = NULL;
+    gcoap_listener_t *listener = NULL;
     sock_udp_ep_t *observer    = NULL;
     gcoap_observe_memo_t *memo = NULL;
     gcoap_observe_memo_t *resource_memo = NULL;
 
-    _find_resource(pdu, &resource, &listener);
-    if (resource == NULL) {
-        return gcoap_response(pdu, buf, len, COAP_CODE_PATH_NOT_FOUND);
-    }
-    else {
-        /* used below to ensure a memo not already recorded for the resource */
-        _find_obs_memo_resource(&resource_memo, resource);
+    switch (_find_resource(pdu, &resource, &listener)) {
+        case GCOAP_RESOURCE_WRONG_METHOD:
+            return gcoap_response(pdu, buf, len, COAP_CODE_METHOD_NOT_ALLOWED);
+        case GCOAP_RESOURCE_NO_PATH:
+            return gcoap_response(pdu, buf, len, COAP_CODE_PATH_NOT_FOUND);
+        case GCOAP_RESOURCE_FOUND:
+            /* used below to ensure a memo not already recorded for the resource */
+            _find_obs_memo_resource(&resource_memo, resource);
+            break;
     }
 
     if (coap_get_observe(pdu) == COAP_OBS_REGISTER) {
@@ -349,10 +356,15 @@ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
  *
  * param[out] resource_ptr -- found resource
  * param[out] listener_ptr -- listener for found resource
+ * return `GCOAP_RESOURCE_FOUND` if the resource was found,
+ *        `GCOAP_RESOURCE_WRONG_METHOD` if a resource was found but the method
+ *        code didn't match and `GCOAP_RESOURCE_NO_PATH` if no matching
+ *        resource was found.
  */
-static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
+static int _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
                                             gcoap_listener_t **listener_ptr)
 {
+    int ret = GCOAP_RESOURCE_NO_PATH;
     unsigned method_flag = coap_method2flag(coap_get_code_detail(pdu));
 
     /* Find path for CoAP msg among listener resources and execute callback. */
@@ -363,9 +375,6 @@ static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
             if (i) {
                 resource++;
             }
-            if (! (resource->methods & method_flag)) {
-                continue;
-            }
 
             int res = strcmp((char *)&pdu->url[0], resource->path);
             if (res > 0) {
@@ -376,16 +385,20 @@ static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
                 break;
             }
             else {
+                if (! (resource->methods & method_flag)) {
+                    ret = GCOAP_RESOURCE_WRONG_METHOD;
+                    continue;
+                }
+
                 *resource_ptr = resource;
                 *listener_ptr = listener;
-                return;
+                return GCOAP_RESOURCE_FOUND;
             }
         }
         listener = listener->next;
     }
-    /* resource not found */
-    *resource_ptr = NULL;
-    *listener_ptr = NULL;
+
+    return ret;
 }
 
 /*