Skip to content

AI translation

This page was translated from German with AI. If in doubt, the German original applies.

Error codes

A transmission to DIWASS can fail at two completely different levels. The two levels have different error formats, appear in different places in the response, and call for different reactions. If you mix them up, you end up with error handling that considers rejected documents delivered.

This page describes both levels, shows where the details can be found in each case, and lists the known business error codes of DIWASS. How the BMU interface reports errors is described in the BMU section.

Two error levels

Transport error Business rejection
Reported by ZEDAL platform DIWASS
How to recognize it gRPC status ≠ OK, HTTP ≥ 400 Error code in the response body
Call technically successful no yes — typically HTTP 200
Error format gRPC status code + detail text code + description per finding
Timing synchronous partly synchronous, partly asynchronous
Reaction Repeat the call, check access/parameters Correct the document and transmit it again

The most important sentence on this page

A business rejection is contained in a technically successful response. An integrator who only checks the HTTP status or the absence of an RpcException never sees a rejected transmission. Both levels must be evaluated separately.

The path of a document and the points where it can fail:

flowchart TD
    A[Client] -->|"gRPC / REST"| B[ZEDAL platform]
    A -.->|"Transport error:<br/>RpcException / HTTP ≥ 400"| A
    B --> C{Schema check}
    C -->|"violation"| D["ValidationErrors<br/>(RPC still succeeds)"]
    C -->|"compliant"| E[Transfer to DIWASS]
    E --> F{DIWASS response}
    F -->|"statusCode = OK"| G[accepted]
    F -->|"statusCode = WARNING"| H["accepted, with warnings"]
    F -->|"statusCode = NOTOK"| I["rejected, with error list"]
    I --> J["TransferHistory / LastError<br/>DiwassTransferFailedException"]

Within the business level there are two further stages that are not the same:

  • Schema validation by ZEDAL — synchronous, field-specific, with a path into the document. Ends up in ValidationErrors and does not make the call fail.
  • Business validation by DIWASS — mostly asynchronous, after the transfer. Ends up in the transfer history and in the transfer details. The codes from the catalog below come from this stage.

A document can be schema-compliant and still be rejected by DIWASS. The reverse case also exists: DIWASS enforces obligations that the generated schema does not express — see The schema is not a sufficient pre-check.


Transport errors

gRPC

A failed call throws an RpcException. Two fields need to be evaluated:

Field Content
Status.StatusCode gRPC status code — the machine-readable classification
Status.Detail Free text from the server, structured differently depending on the platform (see below)
try
{
    await handler.SendToDiwass();
}
catch (RpcException ex)
{
    // Transport level: the call did not get through.
    Console.Error.WriteLine($"{ex.Status.StatusCode}: {ex.Status.Detail}");
}

REST

The REST gateway translates the gRPC status into an HTTP status and puts the original status in the response body:

{
  "code": 3,
  "message": "INVALID_DOCID(6b4575ne)",
  "details": []
}

code is not the HTTP status

The code field carries the numeric gRPC status code, not the HTTP status. 3 is INVALID_ARGUMENT and arrives as HTTP 400. If you check code, you must use the gRPC numbering.

The mapping is hard-wired:

gRPC status HTTP
OK 200
INVALID_ARGUMENT, FAILED_PRECONDITION, OUT_OF_RANGE 400
UNAUTHENTICATED 401
PERMISSION_DENIED 403
NOT_FOUND 404
ALREADY_EXISTS, ABORTED 409
RESOURCE_EXHAUSTED 429
CANCELLED 499
UNIMPLEMENTED 501
UNAVAILABLE 503
DEADLINE_EXCEEDED 504
all others (including UNKNOWN, INTERNAL, DATA_LOSS) 500

The catch-all case at the end of the table is the most common pitfall: UNKNOWN arrives as HTTP 500. An HTTP 500 is therefore not necessarily a platform defect — it can carry a regular business rejection from the backend, whose detail text is in the message field.

Symbols in the detail text

Parts of the platform report errors as a symbol in the detail text, optionally with the ID of the affected object in parentheses, with multiple findings concatenated with |:

NO_ACCESS(39910-5)|NO_ACCESS(39911-5)

The parentheses do not contain an error number

39910-5 is the ID of the affected ZEDAL object, not part of the error code. If you treat the complete string as the code, you cannot group two errors of the same kind. Split at the first (.

The parentheses can also be empty (INVALID_DOCID()) or missing entirely (UNKNOWN_FORMAT). Observed symbols:

Symbol gRPC status Trigger
INVALID_DOCID INVALID_ARGUMENT Document ID empty or syntactically unusable
INVALID_FILEID INVALID_ARGUMENT File ID empty or syntactically unusable
INVALID_TEMPLATEID INVALID_ARGUMENT Template ID empty or syntactically unusable
INVALID_PAR UNKNOWN Parameter value outside the permitted range; the content of the parentheses names the parameter
NO_ACCESS UNKNOWN Access to another party’s object
DOC_NOT_IN_INBOX UNKNOWN the document is not (or no longer) in the inbox
UNKNOWN_FORMAT UNKNOWN import data in an unrecognized format
SUBMISSION_EXISTS UNKNOWN a submission already exists for the file
GOT_NO_SUBMISSION UNKNOWN the operation requires a submission, but there is none
UNABLE_TO_OPEN UNKNOWN the target object cannot be opened for editing

Not an exhaustive list

These symbols are strings at the server’s throw sites, not a maintained enum. There is no complete catalog for them, and there are duplicates with the same meaning (DOC_NOT_EXISTS / DOCUMENT_NOT_EXISTS, DOC_IS_SECRET / DOCUMENT_IS_SECRET, INVALID_PAR / INV_PAR). Base flow decisions on the gRPC status code, not on the symbol. Use the symbol for diagnostics and logging.

Timeouts

A timeout is a transport error and not a rejection. The document may have arrived anyway. After a timeout: first query the state, then decide — do not blindly send again.

Value Duration Consequence
SDK client default timeout (IZedalClient.DefaultTimeout) 30 s too short for sending DIWASS documents
Push with attachment measured at over 90 s allow at least 180 s
Multi-stage movement chains measured at 2:39 to 4:53 per stage 180 s is not enough there
Third-party updates (authority request for additional information, decision) until they are visible in the ZEDAL data 100–150 s do not query immediately after the event

The timeout is set per call via ZedalCallContext:

var ctx = new ZedalCallContext(timeoutSeconds: 180);
await handler.SendToDiwass(ctx);

Zero does not mean unlimited

0 results in a deadline of “now” and makes every call fail with DEADLINE_EXCEEDED. The SDK therefore rejects 0 with ArgumentOutOfRangeException. Unlimited is ZedalCallContext.NoTimeout (-1).

The EU sets an explicit requirement for retries after errors: technical errors must not be retried immediately, but only after a reasonable waiting period; calls that failed because of faulty data must not be repeated at all without correcting the data. In addition, calls must be made sequentially — each next call only after the previous one has been answered.

Throttling by DIWASS

DIWASS limits the number of concurrent calls. If the limit is exceeded, the platform responds with a server fault whose message text contains ConcurrentRequestsLimitExceededException (observed as HTTP 500 / env:Server, verified on July 27 and 28, 2026).

Throttling is not a business error

The document is fine; the server was busy. This is the only case in which an automatic retry is correct. A backoff in the range of 20 seconds over several attempts has proven effective — along with a log entry per retry, so that a run does not silently appear successful while the other side was in fact overloaded.

Detect throttling narrowly by exactly this marker and do not automatically retry anything else. A retry on a business error only produces the same error again — and violates the EU requirement above.

You can avoid throttling by making calls strictly sequentially. Multi-stage flows — such as a movement chain across several carriers — are very likely to run into it when executed in parallel.


Business errors: where to find them

Business findings reach the caller via three separate surfaces. They are not redundant — each carries something the others do not have.

Surface Origin Populated on Structure
ValidationErrors ZEDAL schema check every mutation (Set*, Create*, Submit*) path + error
TransferHistory / LastError Transfer attempts to DIWASS Refresh() via the typed Get* endpoints code + message
DiwassTransferFailedException.Details DIWASS response to the transfer WaitForDiwassTransfer() code + description, separated into errors and warnings

1. Schema validation — ValidationErrors

Every BXA response carries a validation list. If the document is schema-compliant, the list is empty; otherwise it contains one tuple of path and message per violation.

public IList<ValidationError> ValidationErrors { get; protected set; }
public bool HasValidationErrors => ValidationErrors.Count > 0;

ValidationError has exactly two fields:

Field Content
path Object path to the faulty location in the document, JSONPath-like on the proto field names
error Message text for this path

Validation errors do not make the call fail

They are passed through alongside the regular response. No exception is thrown, and the gRPC status remains OK. If you do not check HasValidationErrors, you continue working with a faulty document.

await handler.SetSubmission(submission);

if (handler.HasValidationErrors)
{
    foreach (var v in handler.ValidationErrors)
    {
        Console.Error.WriteLine($"{v.Path}: {v.Error}");
    }
    return; // do not send
}

Refresh() does not reset the list, because the get endpoint does not return any validation errors. The content therefore always comes from the last mutation.

2. Transfer history — TransferHistory, HasError, LastError

The transfer history keeps successes and failed attempts in one list, newest entry first:

public IList<TransferEntry> TransferHistory { get; protected set; }
public bool HasError => TransferHistory.Count > 0 && !TransferHistory[0].Success;
public ErrorInfo LastError => HasError ? TransferHistory[0].Error : null;
Type Field Content
TransferEntry OccurredAt Time of the attempt (UTC)
Success true on successful delivery
RequestName triggering operation, e.g. SetSubmission
Error set if and only if Success == false
ErrorInfo Code machine-readable error code — this is where the codes from the catalog appear
Message Message text

Two properties that are regularly misunderstood:

  • Mutations do not populate the history. Set* and Submit* responses carry no transfer_history; after a mutation the list is empty. It is populated via Refresh(), which calls the typed GetNotification / GetAnnex7 / GetMovement.
  • The history is limited on the server side. Older entries are discarded. It is not a complete audit log.
await handler.Refresh();

if (handler.HasError)
{
    var e = handler.LastError;
    Console.Error.WriteLine($"Transfer failed: {e.Code} — {e.Message}");
}

3. Transfer details — WaitForDiwassTransfer

WaitForDiwassTransfer(timeout, pollInterval) polls the transfer status until it is terminal:

DocumentTransferStatus Meaning Behavior of the method
CREATED Transfer created keeps polling
IN_PROGRESS Transfer in progress keeps polling
DELIVERED_TO_RECIPIENT_INBOX delivered returns
RECEIVED_RECEIPT_POSITIVE positively acknowledged returns
RECEIVED_RECEIPT_NEGATIVE negatively acknowledged — business rejection throws DiwassTransferFailedException
CANCELLED Transfer canceled throws DiwassTransferFailedException

If the status does not become terminal in time, a TimeoutException is thrown — this is not a rejection, see Timeouts.

The exception carries the complete transfer details:

public GetTransferDetailsResponse Details { get; }

Under DiwassTransferDetails they contain two separate lists, Errors and Warnings, each with Code and Description.

try
{
    await handler.WaitForDiwassTransfer(
        timeout:      TimeSpan.FromSeconds(180),
        pollInterval: TimeSpan.FromSeconds(10));
}
catch (DiwassTransferFailedException ex)
{
    foreach (var err in ex.Details.DiwassTransferDetails.Errors)
    {
        Console.Error.WriteLine($"DIWASS error {err.Code}: {err.Description}");
    }
    foreach (var w in ex.Details.DiwassTransferDetails.Warnings)
    {
        Console.Error.WriteLine($"DIWASS warning {w.Code}: {w.Description}");
    }
}
catch (TimeoutException)
{
    // Not a reason for rejection — check the state afterwards via Refresh().
}

pollInterval must be at least 1 second; the method rejects smaller values with ArgumentOutOfRangeException.

Reload after waiting

WaitForDiwassTransfer does not reload the document automatically. Fields added on the server side — such as the assigned notification number — only become visible if you call ReloadFromZedal() afterwards.

Structure of the DIWASS response

Underneath the ZEDAL surfaces there is always the same response structure of the EU interface:

Element Content
statusCode OK, WARNING, or NOTOK
errors 0..n findings, each with code + description
warnings 0..n findings, each with code + description

This is what a real rejection looks like — here for a submission in which an operator ID could not be resolved:

<responseStatus>
  <statusCode>NOTOK</statusCode>
  <errors>
    <code>OPERATOR-ID-NOT-FOUND</code>
    <description languageID="en">Operator 999999999 not found</description>
  </errors>
</responseStatus>
<notificationId>UNKNOWN</notificationId>

Note notificationId = UNKNOWN: for a rejected submission, DIWASS assigns no number. If you read the response without checking it, you store UNKNOWN as the notification number.

Errors and warnings can appear in the same response:

<response>
  <statusCode>NOTOK</statusCode>
  <errors>
    <code>MANDATORY_ELEMENT_MISSING</code>
    <description languageID="en">Element "actualQuantity" is mandatory in block 3
      of Annex VII. Please provide at least one of MassMeasure or VolumeMeasure
      with a positive value.</description>
  </errors>
  <warnings>
    <code>OPTIONAL_ATTACHMENT_MISSING</code>
    <description languageID="en">Attachment references were expected but none
      were found.</description>
  </warnings>
</response>

Three rules for the evaluation follow from this:

  • WARNING is an acceptance. The document is accepted; DIWASS has remarks. Warnings must not be treated like rejections — otherwise you block valid processes.
  • warnings also appears with NOTOK. The list is not tied to the status. The status decides between acceptance and rejection, not the question of which lists are populated.
  • errors is a list. A rejection often names several findings at once. If you only display the first one, you send the user through several rounds of corrections one after another.

In addition to this response structure, the EU interface has its own fault types for cases that never even lead to a business response: PermissionDeniedExceptionType, CertificatePermissionDeniedExceptionType, InvalidParametersExceptionType, and BusinessRulesValidationExceptionType. Each finding in them carries ID, Message, and optionally Field. Via the ZEDAL surfaces they appear as message text, not as a separate code.

The schema is not a sufficient pre-check

DIWASS enforces obligations that are not marked as mandatory in the generated schema. A client-side completeness check against minOccurs alone is therefore not sufficient.

Documented case: RejectedQuantity and RejectionDescription are annotated as minOccurs=0 on the movement receipt certificate. DIWASS nevertheless rejects a transmission without these fields — with REJECTED-QUANTITY-EMPTY and REJECTION-DESCRIPTION-EMPTY. In the Annex VII context, the same field is explicitly minOccurs=1; the discrepancy is therefore intentional and not a transmission error.

The reverse case also exists: mimeCode on attachments is a free mandatory field in the schema without any value restriction — there is no MIME allowlist. The controlled list is typeID, the business classification of the attachment.


Spelling: hyphen vs. underscore

The same error, two spellings

The EU specification list contains the codes with underscores (ATTACHMENT_NOT_FOUND). In the observed responses, DIWASS reports them with hyphens (ATTACHMENT-NOT-FOUND). A direct string comparison between the received code and the catalog entry therefore fails, even though both mean the same error.

Verified pairs — on the left the spelling of the specification list, on the right the observed one:

In the specification list Observed
ATTACHMENT_NOT_FOUND ATTACHMENT-NOT-FOUND
AUTHORITY_ID_NOT_FOUND AUTHORITY-ID-NOT-FOUND
OPERATOR_ID_NOT_FOUND OPERATOR-ID-NOT-FOUND
WASTE_CLASSIFICATION_INVALID_CODE WASTE-CLASSIFICATION-INVALID-CODE
INVALID_NOTIFICATION_CA_CODE_PREFIX INVALID-NOTIFICATION-CA-CODE-PREFIX
BAD_REQUEST_NOTIFIER BAD-REQUEST-NOTIFIER
USER_AUTHORISATION_PERMISSION_AUTHORITY_DENIED USER-AUTHORISATION-PERMISSION-AUTHORITY-DENIED

Do not rely on either spelling

The rule is not consistent: the specification’s sample responses in turn use underscores (MANDATORY_ELEMENT_MISSING, OPTIONAL_ATTACHMENT_MISSING). So there is no spelling you can rely on for comparison. Normalize both sides.

static string NormalizeDiwassCode(string code) =>
    code?.Trim().ToUpperInvariant().Replace('_', '-');

The catalog below lists the codes in the spelling of the respective source. Where a code is only known from observation and is missing from the list, it is written with hyphens.


Catalog of DIWASS error codes

The following 187 codes come from the validation list of the DIWASS specification (Validations-messages.xlsx, columns “Code” and “Label for description”). Codes that actually occurred in the integration and are missing from the list have been added.

How to read the tables:

  • Code — the identifier as the source lists it. Before comparing it with a server response, normalize it first.
  • Label — the translation key that DIWASS associates with this code. to.be.created means: the EU has not yet assigned a description text for this code. This affects 23 of the 187 codes.
  • Meaning — what the code states, derived from the identifier and the label.
  • Cause and resolution — only filled in where the cause is known from a concrete, traced case. A — means “not documented”, not “does not occur”.

This list is not exhaustive

Codes that actually occur are missing from it. REJECTED-QUANTITY-EMPTY, REJECTION-DESCRIPTION-EMPTY, MOVEMENT-SHIPMENT-ORIGIN-ADDRESS-MISMATCH-NOTIFICATION, and MOVEMENT-DATE-BEFORE-NOTIFICATION-DATE occurred in the integration but are not in any version of the specification list. They are included below in their respective topic group and marked as (not in the list). Treat every unknown code as a valid error and report it to us — that is the only way the list grows.

The label is not a unique key

Several codes share the same translation key. participation.party.not.allowed stands for seven different codes, and waste.notification.shipment.date.empty for two. Always base your logic on the code, never on the label.

Waste classification and waste details

Code Label Meaning Cause and resolution
WASTE_CLASSIFICATION_INVALID_CODE waste.error.classification.code A waste code is invalid — the value itself, not its absence. Most common cause: missing group spaces. DIWASS expects EU waste codes as 01 03 06, not 010306; hazardous waste additionally with an asterisk (01 04 07*). None of the 890 codes in the official LoW list appears there without spaces. Second cause: outdated listID. The permitted list names are no longer a schema enum but loose tokens that are checked on the server side — currently including LoW, Basel_A, Basel_B, OECD, y-code, h-code, un_class, wsr_a3/wsr_a3a/wsr_a3b/wsr_a4, hp_codes, customs_codes, nat_exp/nat_imp, un_no, un_shipping, Other, unlisted. The old values (BASEL, EWL, YCODE, NATEXP, UNNUM, ANNEX3A, …) pass the schema but are rejected by the server. Third cause: HP code in the H code field. HP codes belong in the hp_codes list, and there without the EU suffix — even though the regulation text provides for HP14 EU in field 14 (viii). Field (viii) carries only Basel H codes.
WASTE_CLASSIFICATION_REQUIRED waste.notification.waste.classification.required The waste classification is missing entirely. To be distinguished from WASTE_CLASSIFICATION_INVALID_CODE: this code means “not present”, that one “present but invalid”.
USUAL_DESCRIPTION_MANDATORY waste.notification.usual.description.must.exist The usual description of the waste is missing. —
DESIGNATION_DESCRIPTION_REQUIRED waste.notification.designation.description.required The designation and composition of the waste are missing. —
PHYSICAL_CHARACTERISTICS_CODES_REQUIRED waste.notification.physical.characteristics.codes.required The codes for the physical characteristics are missing. —
PHYSICAL_CHARACTERISTICS_DESCRIPTION_REQUIRED waste.notification.physical.characteristics.description.required The description of the physical characteristics is missing. —
PACKAGING_TYPE_CODES_REQUIRED waste.notification.packaging.type.codes.required The packaging type is missing. The DIWASS packaging list is not identical to the classic notification list: it additionally contains “bales” as 9, which moves “other” to 10. Never check against a numeric literal, but against the list from which the field is populated.
PACKAGING_SPECIAL_HANDLING_REQUIRED waste.notification.packaging.special.handling.required Information on special handling requirements is missing. —
OPERATIONS_CODES_REQUIRED waste.notification.operations.codes.required The D/R codes of the operation are missing. —
OPERATIONS_TECHNOLOGY_REQUIRED waste.notification.operations.technology.required The information on the technology employed is missing. —
OPERATIONS_REASON_REQUIRED waste.notification.operations.reason.required The reason for the shipment is missing. —
DISPOSAL_RECOVERY_DOES_NOT_MATCH disposal.recovery.does.not.match Disposal and recovery do not match. —
CUSTOM_CODES_MANDATORY custom.codes.mandatory Customs codes are mandatory for this process. Customs codes belong in the customs_codes list.
MASS_VOLUME_NOT_FOUND mass.volume.not.found The quantity (mass or volume) is missing. —

Parties and contacts

Code Label Meaning Cause and resolution
NOTIFIER_OPERATOR_IS_REQUIRED waste.notification.notifier.must.exist The notifier is missing. —
CONSIGNEE_OPERATOR_IS_REQUIRED waste.notification.consignee.must.exist The consignee is missing. —
WASTE_PRODUCER_OPERATOR_IS_REQUIRED waste.notification.producer.must.exist The waste producer is missing. —
CARRIER_OPERATOR_IS_REQUIRED waste.notification.carrier.must.exist The carrier is missing. —
TREATMENT_FACILITY_OPERATOR_IS_REQUIRED waste.notification.facility.must.exist The treatment facility is missing. —
ARRANGER_OPERATOR_IS_REQUIRED waste.notification.arranger.must.exist The arranger is missing. —
NOTIFIER_CONTACT_IS_REQUIRED waste.notification.notifier.contact.must.exist The notifier’s contact details are missing. —
CONSIGNEE_CONTACT_IS_REQUIRED waste.notification.consignee.contact.must.exist The consignee’s contact details are missing. —
PRODUCER_CONTACT_IS_REQUIRED waste.notification.producer.contact.must.exist The producer’s contact details are missing. —
CARRIER_CONTACT_IS_REQUIRED waste.notification.carrier.contact.must.exist The carrier’s contact details are missing. —
FACILITY_CONTACT_IS_REQUIRED waste.notification.facility.contact.must.exist The facility’s contact details are missing. —
ARRANGER_CONTACT_IS_REQUIRED waste.notification.arranger.contact.must.exist The arranger’s contact details are missing. —
CONSIGNEE_CONTACT_IS_MISSING waste.notification.consignee.contact.must.exist Second code with the same label as CONSIGNEE_CONTACT_IS_REQUIRED. —
PRODUCER_CONTACT_IS_MISSING waste.notification.producer.contact.must.exist Second code with the same label as PRODUCER_CONTACT_IS_REQUIRED. —
CARRIER_CONTACT_IS_MISSING waste.notification.carrier.contact.must.exist Second code with the same label as CARRIER_CONTACT_IS_REQUIRED. —
FACILITY_CONTACT_IS_MISSING waste.notification.facility.contact.must.exist Second code with the same label as FACILITY_CONTACT_IS_REQUIRED. —
ARRANGER_CONTACT_IS_MISSING waste.arranger.contact.missing The arranger’s contact details are missing. —
OPERATOR_NOTIFIER_NAME_EMPTY waste.error.invalid.notifier.name The notifier’s name is empty. —
OPERATOR_CONSIGNEE_NAME_EMPTY waste.error.invalid.consignee.name The consignee’s name is empty. —
OPERATOR_CARRIER_NAME_EMPTY waste.error.invalid.carrier.name The carrier’s name is empty. —
OPERATOR_TREAT_FAC_NAME_EMPTY waste.error.invalid.treat.fac.name The treatment facility’s name is empty. —
OPERATOR_FIELD_MISSING waste.operator.field.missing A mandatory field is missing on an operator. —
PRODUCER_IS_MISSING waste.notification.producer.required The producer is mandatory for this process and is missing. —
PRODUCERS_NOT_ALLOWED waste.notification.producer.not.allowed No producers are permitted in this constellation. —
WASTE_PRODUCER_OPERATOR_DUPLICATE waste.notification.producer.duplicate The same producer is entered more than once. —
CARRIER_OPERATOR_DUPLICATE waste.notification.carrier.duplicate The same carrier is entered more than once. —
TREATMENT_FACILITY_OPERATOR_DUPLICATE waste.notification.facility.duplicate The same facility is entered more than once. —
DUPLICATE_OPERATOR_ID waste.notification.duplicate.operator.id The same operator ID occurs more than once. —
NON_SUBSEQUENT_FACILITY_IS_REQUIRED waste.notification.non.subsequent.facility.must.exist A final (non-subsequent) facility is missing. A notification lists 1 + n facilities. Exactly one of them must be the final one. The position in the chain is controlled by the three indicators in FacilityType.OperationalIndicators.
NON_SUBSEQUENT_FACILITY_MANY waste.notification.non.subsequent.facility.many More than one final facility is specified. As above — exactly one facility may have no successor.
CONFIDENTIAL_EXPLANATION_MISSING waste.notification.facility.confidential.explanation.required The justification for the facility’s confidentiality flag is missing. —
SIGNATURE_IS_REQUIRED waste.notification.signature.required A signature is missing. —
SIGNATURES_ARE_REQUIRED waste.notification.signatures.required Several signatures are missing. —
SIGNATURE_MISMATCH waste.notification.signatures.no.match The signature does not match the expected party. —
DECLARATION_EMAIL_IS_MISSING waste.notification.signatures.email.required The email address for the declaration is missing. —
DECLARATION_DOES_NOT_MATCH_PARTY waste.declaration.mismatch.party The declaration does not belong to the specified party. —
DECLARATION_SIZE waste.declaration.size The number of declarations is incorrect. —
DECLARATION_PRODUCER_SIZE_DOES_NOT_MATCH_PRODUCERS_SIZE declaration.producers.size.mismatch The number of producer declarations differs from the number of producers. Exactly one declaration per producer.
PRODUCER_DECLARATION_NOT_FOUND waste.producer.declaration.not.found The declaration for a producer is missing. —

Directory, authorities, and countries

Code Label Meaning Cause and resolution
AUTHORITY_ID_NOT_FOUND waste.authority.id.not.found The specified authority could not be resolved. Actual message text: AUTHORITY-ID-NOT-FOUND: Authority <code> not found. This is a statement about jurisdiction, not about existence. Not every WSR authority may act as competent authority of transit, and the authority directory does not say which ones may. Documented by a contrasting pair in the same test run: BE004 and BE002 are accepted as transit authorities, BE01 and BE003 are rejected; DE014 is accepted as export and import authority in the same document and rejected as competent authority of transit. All authorities of a country return identical activity data in the directory — authorities that can act for transit and those that cannot are not distinguishable there. The error only surfaces on submit. A second, independent path to the same message: the authority search FindActivities only finds results via the alpha-2 country code ("BE"). The same call with the numeric code ("056") returns 0 hits — without an error, without an exception, simply an empty list. When you get this message, first determine which of the two paths produced it.
AUTHORITY_ID_MISMATCH waste.authority.id.mismatch The authority ID does not match the expected value. —
AUTHORITY_NOT_FOUND to.be.created The authority was not found. —
COMPETENT_AUTHORITY_NOT_FOUND competent.authority.not.found The competent authority was not found. —
AUTHORITY_IS_REQUIRED to.be.created Authority information is missing. —
AUTHORITY_DOMAIN_NOT_FOUND to.be.created The authority’s domain was not found. —
AUTHORITY_DOMAIN_DONT_MATCH_DOCUMENT to.be.created The authority’s domain does not match the document type. —
NOT_NOTIFICATION_AUTHORITY not.notification.authority The authority is not competent for this notification. —
AUTHORITY_CANNOT_BE_CONNECTED participation.party.not.allowed The authority may not be involved in this role. Seven codes share this label — the distinction lies solely in the code.
AUTHORITY_DISPATCH_CANNOT_BE_CONNECTED participation.party.not.allowed The competent authority of dispatch may not be involved. —
AUTHORITY_DESTINATION_CANNOT_BE_CONNECTED participation.party.not.allowed The competent authority of destination may not be involved. —
AUTHORITY_TRANSIT_CANNOT_BE_CONNECTED participation.party.not.allowed The competent authority of transit may not be involved. See AUTHORITY_ID_NOT_FOUND — competence for transit cannot be derived from the directory.
AUTHORITY_HAS_TO_BE_CONNECTED participation.party.not.allowed The authority must be involved. —
AUTHORITY_DISPATCH_IS_CONNECTED_AND_MANAGE_NOTIFIERS participation.party.not.allowed The competent authority of dispatch is connected and manages notifiers. —
AUTHORITY_DISPATCH_IS_CONNECTED_AND_DONT_MANAGE_NOTIFIERS participation.party.not.allowed The competent authority of dispatch is connected but does not manage notifiers. —
PARTICIPATION_PARTY_NOT_AUTHORITY participation.party.not.authority The party listed as an authority is not one. —
PARTICIPATION_PARTY_001 participation.party.not.allowed Participation of this party is not permitted. In the source, a truncated code fragment follows the label — an artifact of the list, not part of the key.
AUTHORITY_IS_NOT_IN_EU to.be.created The authority is located outside the EU. —
OPERATOR_IS_NOT_IN_EU to.be.created The operator is located outside the EU. —
TRANSIT_AND_DESTINATION_ARE_NOT_EU to.be.created Neither the country of transit nor the country of destination is in the EU. —
OPERATOR_NOT_FOUND to.be.created The operator was not found. —
OPERATOR_ID_NOT_FOUND waste.operator.id.not.found The operator ID could not be resolved. Actual message text: Operator <id> not found. The ID in OperatorInternalID does not exist in the DIWASS operator directory. Resolve operator IDs via the directory before assembling the document; do not guess them or copy them from test data. The submission is rejected entirely and carries notificationId = UNKNOWN in the response.
CA_CODE_NOT_FOUND ca.code.not.found The CA code does not exist. DIWASS maintains CA codes in different lengths (four and five characters, e.g. DE01 and DE014). A naive StartsWith does not distinguish between the two.
CA_CODE_LENGTH_ISSUE ca.code.length.issue The CA code has an invalid length. See above — the length is not uniform.
CA_CODE_COUNTRY_NOT_FOUND ca.code.country.not.found No country can be resolved for the CA code. —
COUNTRY_NOT_FOUND country.not.found The country code was not found. In the document, the country code is three-digit numeric with a leading zero (056, XSD pattern \d\d\d). A two-character value is not rejected on business grounds; it is already discarded by the schema and never reaches the business logic. In the directory lookup, the opposite applies: only alpha-2 (BE) works there.
COUNTRY_INFO_NOT_FOUND to.be.created No master data is available for the country. —
DISPATCH_IS_REQUIRED waste.dispatch.required The country of dispatch is missing. —
DISPATCH_COUNTRY_NOT_FOUND waste.dispatch.country.not.found The country of dispatch was not found. —
DESTINATION_IS_REQUIRED waste.destination.required The country of destination is missing. —
DESTINATION_COUNTRY_NOT_FOUND waste.destination.country.not.found The country of destination was not found. —
TRANSIT_COUNTRY_NOT_FOUND waste.transit.country.not.found The country of transit was not found. —
FACILITIES_ARE_OUT_OF_EXPECTED_LOCATION to.be.created Facilities are located outside the expected area. —
FACILITY_NOT_PRE_CONSENTED facility.not.preconsented The facility does not have pre-consent. —
ADDRESS_NOT_FOUND address.not.found The address was not found. —
SHIPMENT_ORIGIN_ADDRESS_REQUIRED waste.notification.shipment.origin.address.required The shipment origin address is missing. —
SHIPMENT_ORIGIN_ADDRESS_MISSING waste.notification.shipment.origin.address.required Second code with the same label as SHIPMENT_ORIGIN_ADDRESS_REQUIRED. —
SHIPMENT_ORIGIN_ADDRESS_BAD waste.notification.shipment.origin.address.bad The shipment origin address is unusable. —
SHIPMENT_ORIGIN_ADDRESS_PARTY waste.notification.shipment.origin.address.party The shipment origin address does not match the specified party. —
MOVEMENT-SHIPMENT-ORIGIN-ADDRESS-MISMATCH-NOTIFICATION (not in the list) The shipment origin address in the movement document differs from the address in the consented notification. ShipmentOriginAddress is optional in the movement document — unlike in the notification, where the same structure is mandatory. If it is set, DIWASS checks it against the notification and rejects any discrepancy. If it is omitted, DIWASS takes the address from the notification and the push goes through. Recommendation: do not set the field in the movement document unless you explicitly want this check to be performed.

Quantities and shipments

Code Label Meaning Cause and resolution
SHIPMENTS_NUMBER_REQUIRED waste.notification.shipments.number.required The total intended number of shipments is missing. This is field 4 of the notification. The number of movement documents must not exceed this total; a properly canceled document does not count, one that has simply been left lying around does.
MOVEMENT_TEMPLATE_INVALID_TOTAL_NUMBER waste.error.mov.template.invalid.total.number The total number in the movement document is invalid. See above — the intended number of shipments from field 4 has been used up, or the value contradicts the notification.
INDIVIDUAL_SHIPMENT_REQUIRED waste.notification.individual.shipment.required An individual shipment must be specified for this type of shipment. —
INDIVIDUAL_SHIPMENT_SHOULD_BE_ONE one.individual.shipment For an individual shipment, exactly one shipment is permitted. —
INTENDED_FIRST_DEPARTURE_REQUIRED waste.notification.intended.period.first.departure.required The first intended departure date is missing. —
INTENDED_LAST_DEPARTURE_REQUIRED waste.notification.intended.period.last.departure.required The last intended departure date is missing. —
SHIPMENT_DATE_EMPTY waste.notification.shipment.date.empty The shipment date is missing. —
SHIPMENT_DATE_MISSING waste.notification.shipment.date.empty Second code with the same label as SHIPMENT_DATE_EMPTY. —
MOVEMENT-DATE-BEFORE-NOTIFICATION-DATE (not in the list) The start date of the movement document is outside the shipment period of the notification. The period is stated in the consented notification as ShipmentPeriod with FirstStartDate and LastStartDate. The start date of the movement document must lie within this window. A hard-coded date in test data drifts out of the window over time and then breaks silently.
REJECTED-QUANTITY-EMPTY (not in the list) The rejected quantity is missing on the receipt certificate. The field RejectedQuantity on the movement receipt certificate is minOccurs=0 in the schema, but DIWASS still rejects a transmission without it. Always set it. In the Annex VII context, the same field is explicitly mandatory — the discrepancy is intentional.
REJECTION-DESCRIPTION-EMPTY (not in the list) The reason for the rejection is missing on the receipt certificate. Like REJECTED-QUANTITY-EMPTY: optional in the schema, mandatory on the server side.

Attachments

Code Label Meaning Cause and resolution
ATTACHMENT_NOT_FOUND attachment.not.found The referenced attachment is unknown to DIWASS. Typical cause: a ZEDAL interim ID instead of a DIWASS ID. An upload via the ZEDAL document path stores the attachment temporarily and assigns a temporary identifier of the form ZEDAL_TMP_ATT_ID_<n>_<m>. This identifier only works for retrieval via the same path — DIWASS does not know it. A central DIWASS attachment ID has the form <digits>ATT. Only the DIWASS ID can be used as the attachmentIdentifier on a document.
ATTACHMENTS_NOT_FOUND attachments.not.found Several referenced attachments are unknown. As above.
ATTACHMENT_MUST_EXIST attachment.must.exist An attachment is mandatory for this process. —
ATTACHMENT_TYPE_EMPTY waste.error.invalid.attachment.type The business classification of the attachment is missing. This refers to typeID — the controlled list (DealerBrokerContract, LiabilityInsurance, FinancialGuarantee, WasteAnalysis, FacilityPermit, TakebackInformation, …). Not mimeCode: that is a free mandatory text field without an allowlist.
ATTACHMENT_TYPE_OTHER waste.error.attachment.type.other.no.comment The explanatory comment for the classification “other” is missing. —
ATTACHMENT_FILE_EMPTY waste.error.invalid.attachment.file The attachment has no content. —
LINKED_ATTACH_NOT_FOUND to.be.created A linked attachment was not found. In the source, a truncated code fragment follows the code ((Builder.warning(i18n) — an artifact of the list, not part of the code.
ATTACH_INDICATOR_NOT_MATCH to.be.created The attachment indicator does not match the files actually attached. Artifact in the source, as with LINKED_ATTACH_NOT_FOUND.

Numbers and formats

Code Label Meaning Cause and resolution
INVALID_NOTIFICATION_CA_CODE_PREFIX invalid.notification.ca.code.prefix The prefix of the notification number does not match the CA code provided. The notification number is structured as <CA code><YY><serial number>i, example BE0125000538i. The prefix is the code of the competent authority at the place of dispatch — in the document ExportState.CompetentAuthority.CompetentAuthorityID, in the user interface block 15 b, column for the country of export/dispatch. The number can therefore only be requested once this block has been filled in. Watch out for the length: DIWASS maintains CA codes with four and five characters (DE01 alongside DE014); the assigned number does not necessarily carry the full code of the document.
INVALID_NOTIFICATION_FORMAT invalid.notification.format The notification number has an invalid format. Format as above.
DUPLICATED_NUMBER waste.notification.number.already.exist The notification number has already been assigned. Do not retry without a new number — a repeated call with the same number fails in exactly the same way.
NUMBER_EMPTY waste.notification.number.empty The notification number is missing but is mandatory here. —
NUMBER_IS_NOT_EMPTY waste.notification.number.not.empty A notification number is set although none may be present here. Occurs on creation when the number is to be assigned by the server.
NOTIFICATION_NUMBER_NOT_PRESENT to.be.created The notification number is missing. —
NOTIFICATION_NUMBER_IS_NOT_EMPTY to.be.created A notification number is set although none may be present. —
SUBMISSION_MUST_EXIST waste.notification.number.not.exist No submission exists for the specified number. —
MOVEMENT_MUST_EXIST waste.movement.number.do.not.exist No movement document exists for the specified number. Do not confuse the two number formats: the ZEDAL transport paper number <NotificationId>.<sequence> without MOV, and the DIWASS movement ID <NotificationId>.<sequence>MOV. The sequence number is not reserved on the server side; it comes from GetNextSequenceNumber(notificationId).
TRANSPORT_MUST_EXIST waste.transport.number.do.not.exist No transport exists for the specified number. —
CERTIFICATE_MUST_EXIST waste.certificate.number.do.not.exist No certificate exists for the specified number. —
INVALID_ANNEX7_NUMBER_PREFIX invalid.annex7.prefix The prefix of the Annex VII number is invalid. —
INVALID_ANNEX7_NUMBER_FORMAT invalid.annex7.format The Annex VII number has an invalid format. —
ANNEX7_NUMBER_NOT_FOUND annex7.not.found No document exists for the Annex VII number. —
ANNEX7_NUMBER_SEQUENCE_NOT_FOUND annex7.sequence.not.found The sequence of the Annex VII number was not found. —
ANNEX7_NUMBER_SEQUENCE_LENGTH_ISSUE annex7.sequence.length.issue The sequence of the Annex VII number has an invalid length. —
MISSING_LANGUAGE_DESCRIPTION missing.language.description The language specification for a multilingual field is missing. —
INVALID_LANGUAGE_DESCRIPTION invalid.language.description The language specification is invalid. —

Lifecycle and order

Code Label Meaning Cause and resolution
SUBMISSION_DOC_EMPTY waste.notification.invalid.submission.document The submission document is missing or empty. —
DECISION_MUST_EXIST waste.decision.not.exist The process requires a decision, but there is none. —
DECISION_ALREADY_EXIST waste.decision.already.exist A decision already exists for this authority. —
DECISION_TYPE_EMPTY waste.error.invalid.decision.type The type of decision is missing. —
DECISION_DATE_EMPTY waste.error.invalid.decision.date The date of the decision is missing. —
DECISION_DOC_EMPTY waste.error.invalid.decision.document The decision document is missing. —
DECISION_TACIT_ONLY_FOR_TRANSIT waste.error.invalid.tacit.decision Tacit consent is only permitted for transit. The competent authorities of dispatch and destination must decide explicitly.
ACKNOWLEDGMENT_DATE_EMPTY waste.error.invalid.ack.date The date of the confirmation of receipt is missing. —
ACKNOWLEDGMENT_DOC_EMPTY waste.error.invalid.ack.document The document for the confirmation of receipt is missing. —
INVOLVED_PARTY_HAS_PROVIDED_ACKNOWLEDGE involved.party.has.provided.acknowledge The party has already confirmed. —
INVOLVED_PARTY_HAS_PROVIDED_DECISION involved.party.has.provided.decision The party has already decided. —
HAS_REQUEST_INFORMATION_OPEN has.request.information.open A request for additional information is still open. An open request for additional information blocks the rest of the process. Pitfall when determining the state: the reply to a request for additional information is in the requestInformation list, not in replyRequestInformation — that one stays empty. Never determine the state from the length of these lists, but from the follow-up intents.
REQUEST_INFORMATION_MUST_EXIST request.information.must.exist The process requires a request for additional information. —
REQUEST_INFORMATION_ID_IS_MANDATORY request.information.id.is.mandatory The ID of the request for additional information is missing. —
REQUEST_CHANGE_MUST_EXIST request.change.must.exist The process requires a request for change. —
REQUEST_CHANGE_ID_IS_MANDATORY request.change.id.is.mandatory The ID of the request for change is missing. —
REQUEST_CHANGE_ROUTE_IS_MANDATORY request.change.route.is.mandatory The route information is missing from the request for change. —
REQUEST_CONTENT_IS_MANDATORY request.content.is.mandatory The content of the request is missing. —
CA_ROLE_IS_MANDATORY ca.role.is.mandatory The role of the authority is missing. —
AGREEMENT_IS_MANDATORY agreement.is.mandatory The consent is missing. —
CONDITION_NOT_MET condition.not.met A precondition of the process is not met. Generic sequencing error. The accompanying message text names the condition.
OPERATORS_CANNOT_CHANGE to.be.created The operators may not be changed in this state. After consent, the document is locked. A change window only opens again through a request for additional information from the authority or through a request for change.
AUTHORITIES_CANNOT_CHANGE to.be.created The authorities may not be changed in this state. As above.
DESTINED_REQUIRED waste.notification.destined.required The information on the intended purpose of the destination is missing. —
DESTINED_PRE_CONSENT_REQUIRED waste.notification.destined.pre.consent.required The information on pre-consent is missing. —
DUE_TAKEBACK_REQUIRED waste.notification.due.takeback.required The information on take-back is missing. —
DUE_ILLEGAL_SHIPMENT_REQUIRED waste.notification.due.illegal.shipment.required The information on illegal shipment is missing. —
PROP_CARRIED_OUT_EMPTY waste.notification.invalid.properly.carried.out The confirmation that the operation was properly carried out is missing. —
MOVEMENT_TEMPLATE_INVALID_DOCUMENT waste.error.mov.template.invalid.document The movement document is not permitted in this context. —
MULTIPLE_DOC_FOR_CARRIER waste.error.multiple.documents.same.carrier There are several documents for the same carrier. —
NOTIFICATION_SCENARIO_NOT_PRESENT to.be.created The shipment scenario is not specified. —
BAD_REQUEST_NOTIFIER bad.request.notifier.and.role Notifier and role do not match. Observed when a notification number is already present in the document when a submission is created. Whether this applies without exception has not been conclusively clarified: on the reservation path, a number assigned in advance is deliberately passed along. If the number is omitted, DIWASS assigns it itself.

Permissions and user context

Code Label Meaning Cause and resolution
WASTE_UNKNOWN waste.unknown Unspecified error. Catch-all code. The accompanying message text is the only information here.
WASTE_ACTION_NOT_ALLOWED waste.user.cannot.execute.action The user is not allowed to perform this action. —
WASTE_CREATE_NOT_ALLOWED waste.user.cannot.create.notification The user is not allowed to create a notification. —
WASTE_UPDATE_NOT_ALLOWED waste.user.cannot.update.notification The user is not allowed to change the notification. —
WASTE_DELETE_NOT_ALLOWED waste.user.cannot.delete.notification The user is not allowed to delete the notification. —
USER_OPERATION_NOT_ALLOWED to.be.created The operation is not permitted for this user. —
USER_CONTEXT_IS_REQUIRED to.be.created The user context is missing. —
USER_HAS_TO_BELONG_TO_OPERATOR to.be.created The user must be assigned to the operator. —
UPDATE_USER_IS_NOT_USER_CREATOR to.be.created Only the creator may make changes. —
INSUFFICIENT_USER_PERMISSIONS waste.insufficient.user.permissions The permissions are insufficient. —
USER_AUTHORISATION_PERMISSION_AUTHORITY_DENIED waste.user.authorisation.permission.authority.denied Access denied — the permission does not cover the object. Occurs, among other cases, when retrieving another party’s attachment: the attachment ID alone is not enough; the credentials must match the operator.
USER_AUTHORISATION_REQUESTS_NOT_FOUND waste.user.authorisation.requests.not.found There are no authorization requests. —
USER_AUTHORISATION_REQUESTS_VALIDATION_ERRORS waste.user.authorisation.requests.validation.errors The authorization requests contain validation errors. —
CURRENT_PARTY_NOT_ALLOWED_ACT_ON_BEHALF waste.current.party.cannot.act.on.behalf The calling party is not allowed to act on behalf of another party. —
ON_BEHALF_CA_MUST_EXIST waste.onbehalf.ca.must.exist When acting on behalf of another party, the represented authority is missing. —
ON_BEHALF_CA_MUST_EXIST_IN_DOCUMENT_CONTENT waste.onbehalf.ca.must.exist.in.document.content The represented authority must also appear in the document content. —
ON_BEHALF_OPERATOR_MUST_EXIST_IN_DOCUMENT_CONTENT waste.onbehalf.operator.must.exist.in.document.content The represented operator must also appear in the document content. —
INVOLVED_PARTY_MUST_EXIST_IN_DOCUMENT_CONTENT waste.involved.party.must.exist.in.document.content The involved party must appear in the document content. —
INVOLVED_PARTY_IS_NOT_AN_OPERATOR_OF_THE_REQUIRED_TYPE involved.party.is.not.an.operator.of.the.required.type The involved party does not have the required operator type. —
IMPORT_SCENARIO_USER_PROFILE_NOT_ALLOWED to.be.created The user profile is not permitted for the import scenario. —
EXTRA_EU_SCENARIO_USER_PROFILE_NOT_ALLOWED to.be.created The user profile is not permitted for shipments outside the EU. —
ENTITY_NOT_FOUND waste.error.entity.not.found The referenced object does not exist. Generic not-found code.

Annex VII (green list)

Code Label Meaning Cause and resolution
GREEN_LISTED_DOCUMENT_NOT_FOUND waste.green.listed.document.not.found The Annex VII document was not found. —
GREEN_LISTED_MOVEMENT_MUST_EXIST waste.green.listed.movement.number.do.not.exist No Annex VII shipment exists for the number. —
GREEN_LISTED_CARRIER_TRANSPORT_MUST_EXIST waste.green.listed.carrier.transport.number.do.not.exist No transport exists for the number. —
GREEN_LISTED_CONSIGNEE_RECEPTION_MUST_EXIST waste.green.listed.consignee.reception.number.do.not.exist No receipt by the consignee exists for the number. —
GREEN_LISTED_FACILITY_RECEPTION_MUST_EXIST waste.green.listed.facility.reception.number.do.not.exist No receipt by the facility exists for the number. —
GREEN_LISTED_FACILITY_COMPLETION_MUST_EXIST waste.green.listed.facility.completion.number.do.not.exist No certificate of completed recovery or disposal from the facility exists for the number. —
GREEN_LISTED_TAKE_BACK_CERTIFICATE_MUST_EXIST waste.green.listed.take.back.certificate.number.do.not.exist No take-back certificate exists for the number. —

Codes from the specification’s sample responses

These two codes are not in the validation list, but they appear in the specification’s sample responses. Their wording is therefore documented, but not their exact trigger condition.

Code Meaning Evidence
MANDATORY_ELEMENT_MISSING A mandatory element is missing. The description names the element and the block, in the example: actualQuantity in block 3 of Annex VII. Sample response with statusCode = NOTOK
OPTIONAL_ATTACHMENT_MISSING Attachment references were expected, but none were found. Appears as a warning, not as an error. the same sample response, in warnings

MANDATORY_ELEMENT_MISSING is the catch-all code for missing mandatory elements. The actual information is in the description — it contains the element name and the block. Show it to the user in full.


Unknown error code

The specification list is incomplete, and DIWASS keeps extending its checks. If you encounter a code that is not listed here, that is not a fault in your integration.

Treat it as a valid rejection — not as a processing failure. Specifically:

  • Do not retry automatically. The EU requirement is clear: a call that failed because of faulty data must not be made again without correcting the data.
  • Log the code and message text unchanged and display them to the user. An unknown code with plain text is more useful to them than “Transmission failed”.
  • No mapping to a substitute code and no silent suppression.

And report it to us. That is the only way this page grows. Useful information:

Information Why
Code and message text, unchanged the spelling is part of the information
triggered operation places the check in the flow
time (UTC) and target system allows server-side matching
ZEDAL document ID identifies the specific process
whether errors or warnings determines whether it was a rejection

BMU

The BmuDocumentApi reports errors as gRPC status, via REST as HTTP status according to the table above. The known cases look like this:

Situation Status Detail
UpdateDocument without doc_xml CANCELLED empty
CreateDocument with an incomplete consignment note at full validation CANCELLED empty
CreateDocument for an acceptance note without ATB role CANCELLED empty
AddLayer on an acceptance note CANCELLED empty
Any call with doc_xml that cannot be loaded as a BMU document INTERNAL technical message of the format

CANCELLED comes from the server here

In these cases the service rejected the request; your client did not cancel anything. The detail is empty, so the cases cannot be told apart from the response. Check your request against the table: XML sent along, matching validation level (XmlOptions), ATB role set, layers only on the consignment note. Via REST, CANCELLED arrives as HTTP 499.