%3CLINGO-SUB%20id%3D%22lingo-sub-1588413%22%20slang%3D%22en-US%22%3EAzure%20API%20Management%20limitation%20workaround%3A%20Return%20404%20instead%20of%20405%20when%20the%20HTTP%20method%20not%20match%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1588413%22%20slang%3D%22en-US%22%3E%3CP%3EThis%20article%20provides%20a%20workaround%20for%20the%20limitation%20on%20API%20Management%20for%20returning%20404%20Operation%20Not%20Found%20instead%20of%20405%20Method%20Not%20Allowed.%20There%20is%20a%20%3CA%20href%3D%22https%3A%2F%2Ffeedback.azure.com%2Fforums%2F248703-api-management%2Fsuggestions%2F32626496-return-status-code-405-instead-of-404-when-wrong-m%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3EAzure%20feedback%3C%2FA%3E%20and%20the%20%3CA%20href%3D%22https%3A%2F%2Fstackoverflow.com%2Fquestions%2F57669530%2Fdoes-azure-apim-supports-405method-not-allowed-status-code%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3EStack%20overflow%3C%2FA%3E%20about%20this%20limitation.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSTRONG%3ECurrent%20Status%20for%20API%20Management%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3EDefining%20API%20in%20APIM%20including%20creating%20the%20resources%20and%20allowed%20methods%20for%20each%20resource.%3C%2FP%3E%0A%3COL%3E%0A%3CLI%3EDefine%20a%20POST%20API%3A%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Ling_Deng_0-1597384960856.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F212357i8AC60A9E8B332427%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20title%3D%22Ling_Deng_0-1597384960856.png%22%20alt%3D%22Ling_Deng_0-1597384960856.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3COL%20start%3D%222%22%3E%0A%3CLI%3ETest%20the%20API%20with%20POST%20method%20via%20Postman%3A%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Ling_Deng_1-1597384960873.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F212358i05234ED29638A9B7%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20title%3D%22Ling_Deng_1-1597384960873.png%22%20alt%3D%22Ling_Deng_1-1597384960873.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3COL%20start%3D%223%22%3E%0A%3CLI%3EChange%20the%20HTTP%20Method%20to%20GET%20or%20other%20methods%2C%20it%20returns%20with%20404%20operation%20not%20found%3A%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Ling_Deng_2-1597384960881.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F212356i5804E600BFE03C23%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20title%3D%22Ling_Deng_2-1597384960881.png%22%20alt%3D%22Ling_Deng_2-1597384960881.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThe%20error%20returned%20by%20APIM%20in%20this%20scenario%20does%20not%20follow%20the%20definition%20of%20HTTP%20status%20code%20strictly.%20There%20was%20feedback%20that%20this%20is%20still%20a%20limitation%20for%20APIM%20and%20product%20team%20updated%20that%20there%20is%20still%20no%20plan%20on%20it.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSTRONG%3EWorkaround%3A%3C%2FSTRONG%3E%3C%2FP%3E%0A%3COL%3E%0A%3CLI%3EHandle%20the%20error%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3EWhen%20APIM%20failed%20to%20identify%20an%20API%20or%20operation%20for%20the%20request%2C%20it%20will%20raise%20a%20configuration%20error%20which%20Responses%20the%20caller%20with%20404%20Resource%20Not%20Found.%20We%20need%20to%20handle%20this%20kind%20of%20configuration%20error%20by%20referring%20the%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fapi-management%2Fapi-management-error-handling-policies%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EError%20Handling%20for%20APIM%3C%2FA%3E%2C%20this%20kind%20of%20error%20can%20be%20specified%20with%20configuration%20Error%20source%20and%20OperationNotFound%20Error%20reason.%26nbsp%3B%20We%20can%20define%20a%20policy%20to%20single%20API%20or%20all%20of%20our%20APIs%20to%20capture%20the%20error%2C%20and%20set%20the%20status%20code%20to%20HTTP%20405.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3COL%20start%3D%222%22%3E%0A%3CLI%3EDefine%20the%20policy%20to%20all%20APIs%3A%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3EPolicy%20Code%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-html%22%3E%3CCODE%3E%20%20%20%20%20%20%3CCHOOSE%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CWHEN%20condition%3D%22%40(context.LastError.Source%20%3D%3D%20%22%20configuration%3D%22%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CRETURN-RESPONSE%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CSET-STATUS%20code%3D%22405%22%20reason%3D%22Method%20not%20allowed%22%3E%3C%2FSET-STATUS%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3CSET-BODY%3E%40%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20new%20JObject(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20JProperty(%22status%22%2C%20%22HTTP%20405%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20JProperty(%22message%22%2C%20%22Method%20not%20allowed%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20JProperty(%22text%22%2C%20context.Response.StatusCode.ToString())%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20new%20JProperty(%22errorReason%22%2C%20context.LastError.Message.ToString())%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20).ToString()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%3C%2FSET-BODY%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FRETURN-RESPONSE%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3C%2FWHEN%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3COTHERWISE%3E%3C%2FOTHERWISE%3E%0A%20%20%20%20%20%20%20%20%3C%2FCHOOSE%3E%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EYou%20may%20wonder%20how%20the%20condition%20context.LastError.Source%20%3D%3D%20%22configuration%22%20%26amp%3B%26amp%3B%20context.LastError.Reason%20%3D%3D%20%22OperationNotFound%22%20will%20specify%20this%20type%20of%20error%2C%20from%20the%20error%20OCP%20trace%2C%20we%20can%20see%20the%20an%20error%20is%20thrown%20with%20message%20in%20Configuration%20section%20%E2%80%9COperationNotFound%E2%80%9D%3A%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Ling_Deng_3-1597385121228.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F212360iDA488E7E99845C28%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20title%3D%22Ling_Deng_3-1597385121228.png%22%20alt%3D%22Ling_Deng_3-1597385121228.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3Ewhen%20this%20type%20error%20occurred%20during%20the%20evaluation%2C%20the%20error%20source%20will%20be%20captured%20as%20configuration.%20It%20will%20not%20forward%20request%20further.%20To%20exclude%20other%20configuration%20error%2C%20we%20need%20specify%20the%20error%20reason%20as%20%E2%80%9COperationNotFound%E2%80%9D.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3COL%20start%3D%223%22%3E%0A%3CLI%3ETest%20the%20API%20with%20wrong%20HTTP%20method%3A%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20image-alt%3D%22Ling_Deng_4-1597385121234.png%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F212361i8083E1FE055467FF%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20title%3D%22Ling_Deng_4-1597385121234.png%22%20alt%3D%22Ling_Deng_4-1597385121234.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ETested%20on%20all%20APIs%20and%20with%20all%20wrong%20methods%2C%20it%20will%20get%20405%20Method%20Not%20Allowed.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSTRONG%3ERelated%20links%3A%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fapi-management%2Fapi-management-error-handling-policies%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%22%3EError%20Handling%20for%20APIM%3C%2FA%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EHope%20this%20can%20be%20useful!%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-1588413%22%20slang%3D%22en-US%22%3E%3CP%3EThis%20article%20provides%20a%20workaround%20for%20the%20limitation%20on%20API%20Management%20for%20returning%20404%20Operation%20Not%20Found%20instead%20of%20405%20Method%20Not%20Allowed.%20There%20is%20a%20-ERR%3AREF-NOT-FOUND-Azure%20feedback%20and%20the%20-ERR%3AREF-NOT-FOUND-Stack%20overflow%20about%20this%20limitation.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1588413%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EAzure%20API%20Management%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1592374%22%20slang%3D%22en-US%22%3ERe%3A%20Azure%20API%20Management%20limitation%20workaround%3A%20Return%20404%20instead%20of%20405%20when%20the%20HTTP%20method%20not%20m%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1592374%22%20slang%3D%22en-US%22%3E%3CP%3EThere%20is%20a%20limitation%20for%20this%20workaround%2C%20it%20will%20show%20405%20also%20when%20the%20request%20url%20is%20not%20found.%3C%2FP%3E%3C%2FLINGO-BODY%3E
Microsoft

This article provides a workaround for the limitation on API Management for returning 404 Operation Not Found instead of 405 Method Not Allowed. There is a Azure feedback and the Stack overflow about this limitation.

 

Current Status for API Management

Defining API in APIM including creating the resources and allowed methods for each resource.

  1. Define a POST API:

Ling_Deng_0-1597384960856.png

 

  1. Test the API with POST method via Postman:

Ling_Deng_1-1597384960873.png

 

  1. Change the HTTP Method to GET or other methods, it returns with 404 operation not found:

Ling_Deng_2-1597384960881.png

 

The error returned by APIM in this scenario does not follow the definition of HTTP status code strictly. There was feedback that this is still a limitation for APIM and product team updated that there is still no plan on it.

 

Workaround:

  1. Handle the error

When APIM failed to identify an API or operation for the request, it will raise a configuration error which Responses the caller with 404 Resource Not Found. We need to handle this kind of configuration error by referring the Error Handling for APIM, this kind of error can be specified with configuration Error source and OperationNotFound Error reason.  We can define a policy to single API or all of our APIs to capture the error, and set the status code to HTTP 405.

 

  1. Define the policy to all APIs:

Policy Code:

 

 

 

      <choose>
            <when condition="@(context.LastError.Source == "configuration" && context.LastError.Reason == "OperationNotFound")">
                <return-response>
                    <set-status code="405" reason="Method not allowed" />
                    <set-body>@{
                    return new JObject(
                        new JProperty("status", "HTTP 405"),
                        new JProperty("message", "Method not allowed"),
                        new JProperty("text", context.Response.StatusCode.ToString()),
                        new JProperty("errorReason", context.LastError.Message.ToString())
                    ).ToString();
                }</set-body>
                </return-response>
            </when>
            <otherwise />
        </choose>

 

 

 

You may wonder how the condition context.LastError.Source == "configuration" && context.LastError.Reason == "OperationNotFound" will specify this type of error, from the error OCP trace, we can see the an error is thrown with message in Configuration section “OperationNotFound”:

Ling_Deng_3-1597385121228.png

 

 

when this type error occurred during the evaluation, the error source will be captured as configuration. It will not forward request further. To exclude other configuration error, we need specify the error reason as “OperationNotFound”.

 

  1. Test the API with wrong HTTP method:

Ling_Deng_4-1597385121234.png

 

Tested on all APIs and with all wrong methods, it will get 405 Method Not Allowed.

 

Related links:

Error Handling for APIM

 

Hope this can be useful!

1 Comment
Microsoft

There is a limitation for this workaround, it will show 405 also when the request url is not found.