Troubleshooting web service errors
Troubleshooting web service errors can be tricky because the root cause of the error can be in multiple places:
- It can be in the client that's calling the web service.
- It can be related to the network between the client and the web service endpoint.
- It can be in the code behind the web service endpoint.
In the following sections, you can learn more about different methods and tools that you can use for troubleshooting web service errors.
HTTP status codes
When you call a web service endpoint, either a Business Central API or from AL using Httpclient datatype, you get an HTTP status code as part of the response. All HTTP status codes that start with 4 (sometimes also written 4xx) are classified as client errors and it is your responsibility to react on these errors and fix them in your code.
In the following table, we list some common 4xx HTTP status codes and suggestions to how to fix them:
HTTP status code | Short name | Description | Suggested solution(s) |
---|---|---|---|
400 | Bad Request | This status code indicates that the server can't or won't process the request due to an error on the client side. For example, it could be a malformed request syntax, header too long, or something else. | The client code that calls the endpoint needs to fix things on their end. For an incoming call of category OData/API, consider using telemetry to find the error. You can also set up a debugger and debug the endpoint code. For an outgoing call, you need to review/debug the AL code that sends the request. |
401 | Access denied | The request failed because it lacks valid authentication credentials for the target resource. | For an incoming call, this is an authorization issue on the Business Central end of this, either in the OnOpenCompany trigger or a permission issue. For an outgoing call, you need to examine the AL code that sets up certificates or sets authorization header(s). |
402 | Payment Required | Indicates that the caller must make a payment to access the requested resource. Typically used in situations where the server requires payment before granting access to the content or service. This status code isn't returned by the Business Central server for incoming calls. |
For an outgoing call, you need to examine the AL code that calls the service and setup error handling to handle this situation. |
403 | Forbidden | This status code is returned when there's some kind of access restriction policy implemented for the requested resource. | For an outgoing call, you need to examine the AL code that sets up certificates (see Httpclient.AddCertificate or sets authorization header(s). Or maybe your app shouldn't call the specified endpoint at all. |
404 | Not found | The resource you're calling doesn't exist (anymore?) | For an incoming call of category OData/API, this endpoint isn't available in metadata. If the endpoint used to work, the issue might be due to uninstalling or updating an app/extension. For UI pages exposed as OData, check if the page was disabled by an administrator. Note: We recommend that you move to APIs. For an outgoing call, you need to examine the URI specified in the AL code calling the endpoint and compare it with the endpoints available on the server you call. |
405 | Method not allowed | The HTTP verb used in the request isn't allowed for the specific URI that an HTTP client requested. | For an incoming call, you need to examine the HTTP method and compare that with what the endpoint supports. One example could be a client calling an API query (which is read-only) using HTTP POST. For on-premises environments where SOAP, OData, or APIs have been turned off, any call to such an endpoint will also return 405 (so check your server configurations if you see those). For an outgoing call, you need to examine the AL code that calls out and compare the Httpclient method used with what the external service offers. |
408 | Request timed out | This status code is returned when the server didn't receive a complete request message within the time that it was prepared to wait. | For an incoming call, this is returned by the Business Central server when the request fails to complete within the limits setup in the server configuration. For online environments, the limits are documented here: Operational Limits for Business Central Online. For on-premises environments, you might be able to adjust the server limits to allow more time for requests to complete. For on-premises environments, you need to change the AL code for the endpoint or call break up the request into multiple requests to make them fit within the time limits. For an outgoing call, you need to investigate the similar limits setup for the external service. Then either change your AL code or break up the request into multiple requests to make them fit within the time limits. |
409 | Conflict | Indicates that the request couldn't be processed because of conflict in the current state of the resource, such as an edit conflict between multiple simultaneous updates. | For an incoming call, this happens when another user has already changed the record(s) that the request is trying to modify. For an outgoing call, you need to look into the documentation for the service you're calling. |
410 | Gone | Indicates that the resource requested was previously in use but is no longer available and won't be available again. | Check you client code/configuration and stop calling this endpoint. |
412 | Precondition Failed | The server doesn't meet one of the preconditions that the requester put on the request header fields. | You need to examine the code that calls the endpoint and check if the settings of request or content HTTP headers match what the service expects. For an incoming call, check if you have supplied the required headers as specified in the API documentation, see API (v2.0) for Business Central for details. For an outgoing call, a common error is to forget to set the Content-Type header (which by default is set to 'text/plain; charset=utf-8'. For more information about content headers, see HttpContent Data Type.) |
413 | Payload Too Large / Request Entity Too Large | The request is larger than the server is willing or able to process. | You need to examine the code that calls the endpoint and adjust the size of the data you send. For OData/API calls, the limit is called Max body size and its current value for BC online is documented here: OData request limits. For SOAP calls, the limit is called Max message size and its current value for Business Central online is documented here: SOAP request limits |
415 | Unsupported Media Type | The request uses a media type that isn't supported by the server/resource. | Could very well be due to wrong Content-Type or Content-Encoding headers in the request. |
418 | I'm a teapot | This HTTP status is exposed as an Easter egg in some services. | If you experience this, there's probably nothing else to do than have a nice cup of tea. Then get back to work afterwards refreshed and ready to fix some more HTTP issues. |
429 | Too Many Requests | This status code is returned when you call too aggressively to the server and it asks you to relax a bit. | The Business Central performance tuning guide explains how you can implement different retry strategies to deal with this type of issue. For more information, see Performance Articles For Developers. |
502 | Bad Gateway | This status code is returned when services in the Business Central data plane are temporarily unavailable. | If you experience this, please retry your request. Note that the Business Central service adds a retry-after HTTP header when returning HTTP status 502. Use this in your web service client code. The Business Central performance tuning guide explains how you can implement different retry strategies to deal with this type of issue. For more information, see Performance Articles For Developers. |
503 | Service Temporarily Unavailable | This status code is returned when the server is down for maintenance or is overloaded. | If you experience this, please retry your request. Note that the Business Central service adds a retry-after HTTP header when returning HTTP status 503. Please use this in your web service client code. The Business Central performance tuning guide explains how you can implement different retry strategies to deal with this type of issue. For more information, see Performance Articles For Developers. |
504 | Gateway Timeout | This status code is returned when your call takes longer than the timeout threshold defined on the server. | The Business Central performance tuning guide explains how you can implement different retry strategies to deal with this type of issue. For more information, see Performance Articles For Developers. |
Web service telemetry
All incoming calls to Business Central web services and outgoing calls to external services are logged to partner telemetry. Telemetry enables you to monitor which endpoints are being used and the category of the web service, like SOAP, OData, or API. You can also see possible failures, which are tracked in the HTTP status codes for the calls.
For more information, see Web service telemetry.
Troubleshooting OData/REST API calls
For calls to OData/REST API endpoints, we offer more details for troubleshooting because these calls also return OData error codes when failures occur.
For more information, see Troubleshooting OData/API calls.
Debugging code called from a web service endpoint
Debugging is the process (and art) of finding and correcting errors. With Visual Studio Code and the AL Language extension for Microsoft Dynamics 365 Business Central, you get an integrated debugger to help you inspect your code and verify that it works as expected.
For information about how to debug code executed from web service endpoints, see Debugging web services.
Which IP addresses or ranges does my environment use?
When you exchange data through APIs (incoming calls) or external services (outgoing calls), you might have to safelist the IP addresses from where the Business Central service is running.
For more information, see FAQ: IP addresses or ranges for the Business Central service
Troubleshooting outgoing calls to external services
Important
Outbound HTTP calls from apps/extensions are blocked by default and must be approved for each extension, otherwise instead of an external call, the system will display the following error message: The request was blocked by the runtime to prevent accidental use of production services.
To enable outbound HTTP calls, go to the Extension Management page in Business Central, and choose Configure. Then, on the Extension Settings page, make sure that Allow HttpClient Requests is selected. This setting must be enabled for each app/extension, including library apps.
For more information, see Call external services with the HttpClient data type.
When an environment is copied, all extensions/apps in the new environment have the property Allow HttpClient Requests set to false. For more information, see Environment copies.
It works in my sandbox but not in production
The environment for a web service endpoint can change how it works. If you see a difference in how it works in your sandbox compared to production, here are some things you can check:
- Does the user calling the web service endpoint exist in both environments?
- Is the user active in both environments?
- If you test with two different users, do they have the same entitlements?
- Are permissions defined the same way in both environments?
- Does the user calling the web service endpoint have the same permissions in both environments?
- For pages/codeunits exposed as OData/SOAP, are they exposed the same way in both environments?
- Are apps/extensions Allow HttpClient Requests properties set the same way in both environments?
- (Only for on-premises) Are API/OData/SOAP enabled the same way in both environments?
Related information
Handling UI Interaction in web service endpoints
Web Services Best Practices
Web service telemetry
Troubleshooting OData/API calls
Debugging web services
Web Services Overview