Azure / Azure/azure-sdk-for-java
[BUG] azure-core-amqp: absent max-message-size on ATTACH is treated as a 0-byte limit, so every send fails against spec-compliant AMQP 1.0 brokers (e.g. ActiveMQ Artemis)
- Dominant language
- Java
- Stars
- 2.6k
- Forks
- 2.2k
- Avg merge
- 2d 8h
- Merged PRs (30d)
- 178
Description
**Describe the bug**
`ReactorSender.getLinkSize()` reads the remote `max-message-size` from the broker's ATTACH frame. When the peer omits the field, `linkSize` is left at its initial value of **0**, and every subsequent send fails immediately with "Size of the payload exceeded maximum message size: 0 kb" — before any bytes are put on the wire.
Per the AMQP 1.0 spec (OASIS AMQP v1.0, §2.7.3 "Attach", field `max-message-size`):
> The maximum message size supported by the link endpoint. […] **If this field is zero or unset, there is no maximum size imposed by the link endpoint.**
So an absent field means *no limit*, not a 0-byte limit — and even a literal `0` would mean *unlimited* per spec. The current handling misreads both cases:
https://github.com/Azure/azure-sdk-for-java/blob/0f5c6c251cd63de545f4a056cf6308fc69562edc/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ReactorSender.java#L399-L405
```java
final UnsignedLong remoteMaxMessageSize = sender.getRemoteMaxMessageSize();
if (remoteMaxMessageSize != null) {
linkSize = remoteMaxMessageSize.intValue();
} else {
logger.warning("Could not get the getRemoteMaxMessageSize. Returning current link size: {}",
linkSize); // linkSize is still 0 here
}
```
The 0 then flows into the size check / encode-buffer allocation in `send(...)` (L223–L233) and the batch path (`batchBufferOverflowError`, L336–L341), so **every** message "exceeds" the limit.
The real Azure Service Bus service always advertises `max-message-size`, which is why this never fires against Azure itself. But brokers that omit the field are spec-compliant. ActiveMQ Artemis never advertises it on its receiving links (no `setMaxMessageSize` call anywhere in `artemis-amqp-protocol` — checked tags 2.31.0 through 2.44.0), so `com.azure:azure-messaging-servicebus` cannot send a single message to an Artemis-backed endpoint. The same applies to any other AMQP 1.0 peer that leaves the field unset.
For comparison, the Python SDK's pyamqp stack is not affected — it falls back to a default when the field is absent.
***Exception or Stack Trace***
```
com.azure.messaging.servicebus.ServiceBusException: Error sending. Size of the payload
exceeded maximum message size: 0 kb, errorContext[NAMESPACE: localhost. ERROR CONTEXT: N/A,
PATH: topic-325c6f9e, REFERENCE_ID: topic-325c6f9etopic-325c6f9e, LINK_CREDIT: 1000]
```
Immediately preceded in the client log by the warning from `getLinkSize()`:
```
Could not get the getRemoteMaxMessageSize. Returning current link size: 0
```
**To Reproduce**
Steps to reproduce the behavior:
1. Point the SDK at any AMQP 1.0 endpoint whose ATTACH response omits `max-message-size` on the broker's receiving link. We hit this with a Service Bus emulator ([floci-az](https://github.com/floci-io/floci-az)) that fronts an unmodified ActiveMQ Artemis broker (`apache/activemq-artemis:2.44.0`, also reproduced on `2.42.0`) for the AMQP data plane. The connection, CBS handshake, and link attach all succeed.
2. Send any message — even a 1-byte payload — with `ServiceBusSenderClient` or `ServiceBusSenderAsyncClient`, to a queue or topic.
3. The send fails immediately with the exception above; nothing reaches the broker.
***Code Snippet***
```java
ServiceBusSenderClient sender = new ServiceBusClientBuilder()
.connectionString(connectionString) // emulator endpoint backed by Artemis
.sender()
.topicName("topic-325c6f9e")
.buildClient();
sender.sendMessage(new ServiceBusMessage("hello")); // throws ServiceBusException: ... 0 kb
```
**Expected behavior**
When the remote ATTACH does not carry `max-message-size` (or carries `0`), the client should treat the link as having no peer-imposed limit, per spec — e.g. fall back to a sane client-side default (the pre-existing 256 KB / 1 MB service defaults, or a configurable value) instead of a 0-byte cap. Sends within that default should succeed.
**Screenshots**
N/A (log/stack trace above).
**Setup (please complete the following information):**
- OS: Windows 11 (host), broker in Linux container via Docker Desktop
- IDE: N/A (Maven CLI)
- Library/Libraries: `com.azure:azure-messaging-servicebus:7.17.x` via `com.azure:azure-sdk-bom:1.2.28`; code path unchanged on current `azure-core-amqp` `main` (0f5c6c2)
- Java version: 21
- App Server/Environment: plain JUnit tests (Maven Surefire); also reproduced from a packaged app
- Frameworks: none required to reproduce
**Additional context**
- Discovered while running Azure SDK compatibility tests against an emulator that uses ActiveMQ Artemis as its AMQP data plane: floci-io/floci-az#128 (contains the full root-cause analysis and spec discussion).
- We are also raising an interop enhancement with the Artemis project to optionally advertise `max-message-size`, but existing released SDK versions would still fail against every current Artemis release, and omitting the field is valid per spec — hence this report.
- A fallback here would benefit every non-Azure AMQP 1.0 broker used with these client libraries, and would match the Python SDK's behavior.
**Information Checklist**
- [x] Bug Description Added
- [x] Repro Steps Added
- [x] Setup information Added
Contributor guide
Assessment
This issue has not been assessed yet.