Receiving worked while sending failed
Marblo could receive Telegram messages, but sending failed with ETIMEDOUT.
Successful reception alone was insufficient evidence that the Telegram
connection was healthy in both directions.
When this happens, examine receiving and sending separately. Establishing which direction succeeds and which fails helps narrow the investigation to the failing side.
The useful comparison here was between connectivity by address family and measured connection latency. The IPv6 path was blocked without a response, while IPv4 connections took around 0.24–0.28 seconds.
Compare connection latency with the attempt timeout
The IPv4 measurement converts to around 240–280ms. Compare that with how long Node's address family autoselection allows a connection attempt to run.
The Node 22 documentation
lists 250ms as the initial default for autoSelectFamilyAttemptTimeout.
The connection options
apply it to each autoselection attempt except the last address before
moving on to the next address.
The measured IPv4 latency straddled that limit. An IPv4 attempt subject to the limit could therefore be cut off before it finished connecting. A reachable path can still need more time than an attempt is allowed.
Check the documentation for your Node version alongside the active settings. Comparing latency and the attempt timeout in the same units makes it easier to see where the wait ends.
Preferring IPv4 alone did not resolve it
Changing DNS results to prefer IPv4 did not restore sending on its own.
The DNS result order setting controls lookup ordering, separately from the connection attempt budget. After changing address order, examine the attempt timeout as well.
Increasing the per-attempt timeout to 2 seconds resolved the issue.
Telegram sending then returned to normal. Node exposes
net.setDefaultAutoSelectFamilyAttemptTimeout()
to adjust that default.
For another environment, start by measuring latency and comparing it with the attempt timeout. Two seconds was the value that restored sending in this environment.
Consider delivery before retrying
Review retry behavior alongside a sending failure. Retrying a message whose delivery status is uncertain carries a risk of duplicate delivery. Before resending based on a failure indication, consider whether delivery can be confirmed.
Builders investigating a similar symptom can follow this sequence:
- Separate receiving from sending. Establish which direction succeeds and which fails.
- Examine each address family and measure latency. Distinguish a path that gives no response from one that takes time to connect.
- Compare timeout defaults with active settings. Revisit the attempt budget even after changing DNS order.
- Verify sending after the change. Confirm outbound recovery separately from successful reception.
- Review duplicate risk before resending. Decide how to confirm and retry messages with uncertain delivery.
In this series
Marblo Build Notes 9: Telegram Conversations with the Orchestrator explores giving direction and receiving progress updates while away. When operating that conversation, verify incoming and outgoing messages individually.
- Marblo Build Notes 1: The Closed Loop Release
- Marblo Build Notes 6: Merge Train
- Marblo Build Notes 9: Telegram Conversations with the Orchestrator
Wrapping up
The Hypemarc Builder Community will keep sharing what we learn while building and operating AI agents, along with resources worth exploring. We'll continue gathering useful resources to share with fellow builders.
- Open chat: AI Builders
- Adoption advice and inquiries: Contact form
- Get the next post: Blog RSS · AI resource library