unicity-aos/aos-ce · warning
Dropped ingress message to blocked topic
Error message
Dropped ingress message to blocked topic: {topic} What it means
The message's topic failed is_allowed_ingress_topic, so the library drops it entirely: it is not forwarded AND it does not retarget the connection's session (session_id: None). This blocks a spoofing vector where an unforwarded message could otherwise redirect a connection onto another session's stream.
Solutions
- Check the logged topic against is_allowed_ingress_topic / the current allowlist and correct the client's topic name
- Update the ingress topic allowlist if this is a legitimate new topic
- Upgrade the client if it uses an outdated topic naming scheme
- If malicious activity is suspected, investigate the client sending off-allowlist topics
Example fix
// before send(topic: "internal/debug-dump") // blocked // after send(topic: "events") // allowlisted topic
Defensive patterns
Strategy: validation
Validate before calling
const ALLOWED: &[&str] = &["events", "logs"];
if !ALLOWED.contains(&msg.topic.as_str()) {
return Err(format!("topic {} is not allowlisted", msg.topic));
} Prevention
- Keep the client's topic list in sync with is_allowed_ingress_topic
- Centralize topic names as constants shared by client and proxy
- Review allowlist changes before deploys that restrict topics
- Investigate repeated blocked-topic warnings as potential probing/spoofing
When it happens
Trigger: A client sends an ingress message whose topic is not in the allowed set; the `if !is_allowed_ingress_topic(topic)` check logs this warning and returns IngressOutcome with newly_bound kept but session_id None.
Common situations: Clients subscribing to topics that were removed or renamed in the allowlist; typos in topic names; a malicious or buggy client probing internal topics; config changes tightening the ingress allowlist after a deploy.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Dropped ingress message: connection bound to
- Unicity AOS health service must bind to 127.0.0.1
- product manifest path must be a regular file
- temporary product manifest path must be a regular file
- AOS capsule directory must be a real directory
AI-assisted analysis of unicity-aos/aos-ce@f6f22024fb (2026-09-13).
Data as JSON: /api/errors/d86d2a3bb2148431.
Report an issue: GitHub.
Appendix: source
Thrown at capsules/capsule-cli/src/lib.rs:596
let (Some(topic), Some(payload)) = (
msg.get("topic").and_then(|t| t.as_str()),
msg.get("payload"),
) else {
// No forwardable body, but the principal still binds the connection
// (e.g. a bare handshake establishes identity for connect-tracking).
// Nothing is forwarded, so the connection's session is never retargeted.
log::warn("Ingress message has no topic/payload; binding only, nothing forwarded");
return IngressOutcome {
newly_bound,
session_id: None,
};
};
if !is_allowed_ingress_topic(topic) {
// A blocked-topic message is neither forwarded nor allowed to retarget
// the connection's session — otherwise a client could spoof itself onto
// another session's stream with an unforwarded message.
log::warn(format!("Dropped ingress message to blocked topic: {topic}"));
return IngressOutcome {
newly_bound,
session_id: None,
};
}
// Always forward under the connection's bound principal. There is no
// `publish_json` (proxy self-identity) fallback for client traffic:
// publishing without a principal would attribute the request to the
// proxy capsule's own (admin-seeded) identity, so any socket client
// could run admin commands (privilege escalation) — or, if the router
// gates on the envelope principal, every admin request would be denied
// for lacking one. A bound connection's traffic always attributes to
// its principal (auto-attribution for un-stamped messages).
if let Err(e) = ipc::publish_json_as(topic, payload, &forward_as) {
log::error(format!("Failed to publish IPC: {e:?}"));
}
View on GitHub (pinned to f6f22024fb)