eclipse-edc / eclipse-edc/Connector

Consumer discards the real termination reason/code received in an incoming TransferTerminationMessage

Open
#5,951 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
424
Forks
300
Avg merge
12h 19m
Merged PRs (30d)
37

Description

**Component:** `org.eclipse.edc.connector.controlplane.services.transferprocess.TransferProcessProtocolServiceImpl`
**Version:** confirmed against `eclipse-edc` core `0.15.1` (as pinned by `tractusx-edc` `0.12.1`), via the actual compiled `edc-runtime.jar` — not source inspection alone.

### Summary

When a transfer is terminated because of a `DataFlow` failure, the provider correctly populates and sends the real failure reason over the wire — but the consumer's own connector silently discards it before persisting its local `TransferProcess`, so the consumer never has access to information the protocol already successfully delivered to it.

### What I found (via `javap -c -p` on the actual runtime jar)

1. On termination, `TransferProcessManagerImpl` builds the outgoing `TransferTerminationMessage` with `.reason(transferProcess.getErrorDetail())` — i.e. the real error string (e.g. an underlying `S3DataSourceException` message) is deliberately included.
2. `JsonObjectFromTransferTerminationMessageTransformer` serializes this `reason` (and `code`) onto the DSP wire message (`addIfNotNull`).
3. On the receiving side, `JsonObjectToTransferTerminationMessageTransformer` correctly parses `reason` back off the wire into the deserialized `TransferTerminationMessage` object.
4. But `TransferProcessProtocolServiceImpl.terminatedAction(TransferTerminationMessage, TransferProcess)` — the handler that actually processes this incoming message — never calls `message.getReason()` or `message.getCode()` at all. It only calls `transferProcess.transitionTerminatingRequested()` and `transferProcess.protocolMessageReceived(message.getId())` before saving. The parsed `reason` value is simply dropped.

I confirmed this live: the same failed transfer showed a populated `errorDetail` on the **provider's** `GET /v3/transferprocesses/{id}` response, and no `errorDetail` field at all on the **consumer's** response for the same transfer.

### Impact

In any real multi-organization dataspace, the consumer of a transfer has no access to the provider's logs or Management API. Today, when a transfer fails on the provider's side, the consumer's own connector receives the real reason over the wire and then throws it away — leaving the consumer with a bare `TERMINATED` state and no way to self-diagnose *why*, even though the information was already delivered to them.

### Suggested fix

`terminatedAction` (or wherever the consumer-side `TransferProcess` is updated from an incoming `TransferTerminationMessage`) should copy `message.getReason()` (and/or `getCode()`) onto the local `TransferProcess`'s `errorDetail`, the same field already used for locally-originated failures.

### Reproduction

1. Configure a push transfer (e.g. `AmazonS3-PUSH`) where the source object doesn't exist.
2. Start the transfer as consumer; it will progress to `STARTED` then `TERMINATED` once the provider's data-plane fails to read the source.
3. `GET /v3/transferprocesses/{id}` on the **provider** shows a populated `errorDetail`.
4. `GET /v3/transferprocesses/{id}` on the **consumer**, for the same transfer, shows no `errorDetail` at all.

Contributor guide

Open the contributing guide

Research direction

Start in org.eclipse.edc.connector.controlplane.services.transferprocess.TransferProcessProtocolServiceImpl, focusing on terminatedAction and how the incoming TransferTerminationMessage updates the local TransferProcess. Review the message transformers to confirm reason and code are available, then reproduce the AmazonS3-PUSH failure and compare provider and consumer GET /v3/transferprocesses/{id} responses. Done means the consumer exposes the received termination detail.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.