Assistance Required – CSID request keeps failing with Invalid-CSR (Sandbox / developer-portal / simulation)

Hello ZATCA Technical Service Provider,

We are setting up the sandbox and starting Phase-2 onboarding by requesting a CSID, but we consistently receive HTTP 400 with Invalid-CSR, despite aligning with the documented requirements. Below is a concise summary of our environment, steps, and what we see on our side. We’d appreciate your guidance to confirm the exact CSR format accepted and any additional requirements we may be missing.
Environment

  • SDK: ZATCA E-Invoice .NET SDK R3.4.5 (fatooraNet.exe)

  • OS/Runtime: Windows 10 / .NET 9.0 (Web API), Visual Studio

  • Mode: Simulation (we pass -sim when generating the CSR via the SDK)

  • Endpoint:
    POST https://gw-fatoora.zatca.gov.sa/e-invoicing/developer-portal/compliance/
    Headers:

    • accept-version: v2

    • accept: application/json

    • (Tried both with and without OTP; sandbox behavior appears the same)

  • VAT: 312536662600003
    CSR Generation (two approaches)

    1. Via SDK (fatooraNet.exe csr -sim)

      • The SDK generates EC/ECDSA keys (stdout shows: “Generate EC Private Key String”).

      • Subject is provided through the properties file (per the SDK template), including:

        • CN = <15-digit VAT>

        • serialNumber = 1-<Make>|2-<Model>|3-<DeviceSerial> (as enforced by the SDK)

        • 2.5.4.97 (organizationIdentifier) = <VAT>

        • OU = VAT, O = <OrganizationName>, C = SA

      • SAN (DirName) contains: UID=<VAT>, T=1100, registeredAddress=RERA7292, businessCategory=Information Technology.

      • CSID response: 400 – {"errorCode":"400","errorCategory":"Invalid-CSR","errorMessage":"The provided Certificate Signing Request (CSR) is invalid."}

    2. Via custom code (BouncyCastle) using RSA-2048 + SHA256

      • We kept the exact same Subject (including the serialNumber triplet) and the SAN DirName values above.

      • We submit a clean Base64 DER (no PEM headers).

      • CSID response: 400 – Invalid-CSR as well.

    Note: Occasionally we also saw 400 Invalid Request when headers/path differed; we corrected this and now consistently use accept-version: v2 and /developer-portal/compliance/.

    Example CSR (brief for confirmation)

    (Example generated via SDK — private key is not shared)

    • CN: 312536662600003

    • serialNumber: 1-HALOUL|2-POSv1|3-00001

    • organizationIdentifier (2.5.4.97): 312536662600003

    • SAN (DirName): UID=312536662600003, T=1100, registeredAddress=RERA7292, businessCategory=Information Technology

    • Key/Signature (SDK): EC / ECDSA

    • Key/Signature (BouncyCastle): RSA-2048 / sha256WithRSAEncryption

      Requests for clarification

      1. Accepted key type for CSID in sandbox:

        • Is EC/ECDSA accepted for CSID today, or is RSA-2048 + SHA256 strictly required?

        • If EC is not accepted, is there an official SDK option (parameter, setting, newer SDK) to force RSA-2048?

      2. serialNumber format in the Subject:

        • We currently use the SDK-enforced triplet 1-<Make>|2-<Model>|3-<DeviceSerial>.

        • Is this format required for CSID, or is an alternative like SA<VAT> still acceptable?

      3. SAN as DirectoryName:

        • For CSID, are the four attributes (UID, T=1100, registeredAddress, businessCategory) mandatory?

        • Is there a definitive list of required OIDs/values for SAN (and any order constraints)?

      4. Official accepted CSR example / schema:

        • Could you share a sample CSR known to be accepted by the sandbox (EC or RSA), or a current, detailed schema for the CSID-specific CSR (Subject + SAN requirements)?
      5. Diagnosis of our current CSR:

        • If possible, please review the attached CSR(s) and indicate which field is causing Invalid-CSR. We can provide both the latest SDK (EC) CSR and the BouncyCastle (RSA-2048) CSR for comparison.

    We appreciate your support. Our goal is to complete the CSID step in sandbox promptly to proceed with Phase-2.
    Kindly advise on the exact CSR requirements and any updates we should apply.

    Best regards,
    Anas AlKassar

Dear @AnasAlkassar

Thanks for reaching out, Welcome to our community.

Kindly note that Sandbox environment is only to clarify the integration steps you can not successfully integrate with ZATCA through sandbox, it can be through Simulation/Production ENV.

However, we noticed that you are using “-sim” command which literally means “The Generated CSR will be for simulation ENV” and you are using it through sandbox URLs.

Our recommendation is to try the same steps using simulation API, you can find API documentation page after login to fatoora portal navigate to simulation portal you will find API documentation tap.

Please do not hesitate to reach out for any further clarification.

Thanks,
Ibrahem Daoud.

Thank you for your support.

To confirm, the CSR structure and required fields we are using match the documented specifications (Subject, SAN/DirName, and relevant OIDs). However, we continue to receive 400 – Invalid CSR.

Could you please confirm whether our current field set is acceptable, and advise if there are any constraints, validation rules, or value restrictions (e.g., allowed formats, lengths, character sets, specific OIDs, or environment-specific values) that we must adhere to for the Simulation CSID request?

Your guidance on any mandatory field values or constraints will help us resolve this quickly.

Best regards,

Anas ALKASSAR
Senior Software Engineer

Istanbul, Turkey

(+90) 536 840 4603

LinkedIn