Share via

OData Filter startswith returning 400 Client Error on SalesInvoiceHeadersV4 in D365 F&O

Basjie | Jirayut Saeung 0 Reputation points
2026-03-18T04:03:17.6933333+00:00

Details: Hi Team,

I am facing an issue while using the startswith filter function with OData API in Dynamics 365 Finance & Operations. Despite following the official documentation, I keep receiving a 400 Client Error (Internal Server Error).

Environment Details:

  • Entity Name: SalesInvoiceHeadersV4
  • Target Field: SalesOrderNumber (String)

Tested URL: https://drpong.operations.dynamics.com/data/SalesInvoiceHeadersV4?$filter=startswith(SalesOrderNumber,'SO')&$top=5

What I have tried:

Verified the Field Name SalesOrderNumber exists in the entity metadata (it does).

Tested with simple eq filter (e.g., $filter=SalesOrderNumber eq 'SO250049110') -> Works fine.

Tested with contains filter -> Fails with 400 Error.

Tried adding cross-company=true -> Still fails.

Error Message: The response returns a 400 Client Error, but the body doesn't provide a specific sub-error code other than Internal Server Error.

Question: Is there any specific configuration required to enable startswith or contains for this entity? Or is this a known limitation for certain string fields in D365 F&O OData?

Any guidance would be greatly appreciated.

Community Center | Not monitored
0 comments No comments

3 answers

Sort by: Most helpful
  1. Gérard Oomens 121.1K Reputation points Volunteer Moderator
    2026-03-18T10:47:34.5566667+00:00

    Post/ask in the Dynamics community:

    Explore Dynamics 365 forums

    0 comments No comments

  2. Basjie | Jirayut Saeung 0 Reputation points
    2026-03-18T04:17:34.1766667+00:00

    Thank you for the initial feedback. I have performed further technical testing to isolate the issue, and the results suggest a Service Implementation Limitation on the SalesInvoiceHeadersV4 entity.

    Test Results:

    1. Basic Request: .../data/SalesInvoiceHeadersV4?$top=1 -> Success (200 OK). The entity itself is accessible.

    Equality Filter: ?$filter=SalesOrderNumber eq 'SO250049110' -> Success (200 OK).

    Range/Function Filters (The Issue):

    startswith(SalesOrderNumber, 'SOM') -> Failed (400 Internal Server Error)

      `SalesOrderNumber ge 'SOM' and SalesOrderNumber lt 'SON'` -> __Failed (400 Internal Server Error)__
      
         `contains(SalesOrderNumber, 'SOM')` -> __Failed (400 Internal Server Error)__
         
    

    Analysis: Since standard OData operators like ge (Greater than) and lt (Less than) are failing on the SalesOrderNumber field—while working fine on other entities—this indicates that the field might be a Virtual Field or lacks the necessary SQL Indexing at the Data Entity level to support range-based queries.

    Request for Resolution:

    Please confirm if SalesOrderNumber in SalesInvoiceHeadersV4 is a Virtual/Computed field that does not support OData filtering.

    If it is a limitation of this specific Version (V4), is there a recommended Alternative Entity or Data Management API approach to filter invoices by Sales Order prefix?

    Are there any Configuration Keys or Entity Refresh steps required to enable advanced filtering for this property?

    Looking forward to your technical guidance.Thank you for the initial feedback. I have performed further technical testing to isolate the issue, and the results suggest a Service Implementation Limitation on the SalesInvoiceHeadersV4 entity.

    Test Results:

    Basic Request: .../data/SalesInvoiceHeadersV4?$top=1 -> Success (200 OK). The entity itself is accessible.

    Equality Filter: ?$filter=SalesOrderNumber eq 'SO250049110' -> Success (200 OK).

    Range/Function Filters (The Issue):

    startswith(SalesOrderNumber, 'SOM') -> Failed (400 Internal Server Error)

      `SalesOrderNumber ge 'SOM' and SalesOrderNumber lt 'SON'` -> __Failed (400 Internal Server Error)__
      
         `contains(SalesOrderNumber, 'SOM')` -> __Failed (400 Internal Server Error)__
         
    

    Analysis: Since standard OData operators like ge (Greater than) and lt (Less than) are failing on the SalesOrderNumber field—while working fine on other entities—this indicates that the field might be a Virtual Field or lacks the necessary SQL Indexing at the Data Entity level to support range-based queries.

    Request for Resolution:

    Please confirm if SalesOrderNumber in SalesInvoiceHeadersV4 is a Virtual/Computed field that does not support OData filtering.

    If it is a limitation of this specific Version (V4), is there a recommended Alternative Entity or Data Management API approach to filter invoices by Sales Order prefix?

    Are there any Configuration Keys or Entity Refresh steps required to enable advanced filtering for this property?

    Looking forward to your technical guidance.

    0 comments No comments

  3. Q&A Assist
    2026-03-18T04:03:44.2233333+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    startswith and contains support depends on how the OData endpoint and schema version are implemented for the specific service.

    From the available information:

    • OData services in Dynamics 365 Business Central and other Microsoft services support startswith, endswith, and contains as OData query functions for string values, but support can vary by implementation and schema version.
    • In some implementations, nested or more advanced function usage is only supported from a specific schema version ($schemaversion=2.1 and later). Earlier schema versions can return errors or undefined results when functions are used in filters.
    • For some APIs, only a subset of properties are filterable, and only certain operators are allowed per property. For example, in Microsoft Graph, the documentation explicitly lists which operators (eq, ne, startswith, endswith, contains, etc.) are supported and shows that not all properties support all operators.

    Applied to the described scenario:

    • The fact that SalesOrderNumber eq 'SO250049110' works but startswith(SalesOrderNumber,'SO') and contains(SalesOrderNumber,'SO') both fail with a 400 error strongly indicates a limitation of the SalesInvoiceHeadersV4 OData implementation rather than a syntax issue.
    • There is no configuration in the provided material that enables or disables startswith/contains per entity; instead, support is determined by the service implementation and schema version.
    • This aligns with other documented cases where only certain operators are supported on specific fields, and unsupported operators result in OData errors.

    Based on the context, this should be treated as a limitation of the SalesInvoiceHeadersV4 OData service for SalesOrderNumber (and possibly for that entity in general) rather than a misconfiguration. Where such limitations exist, the recommended approach is to:

    1. Use equality or range filters that are known to work (eq, ne, gt, ge, lt, le) on supported fields.
    2. Avoid relying on startswith/contains on that entity unless official documentation for that specific API explicitly states support.
    3. If partial matching is required, retrieve a broader set of data using supported filters and apply string filtering in the consuming application.

    There is no configuration step in the provided documentation that would enable startswith or contains for SalesInvoiceHeadersV4, so this behavior should be considered a service limitation or bug that would need to be raised with Microsoft support for that product.


    References:

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.