Troubleshooting
A systematic checklist for the ROS 2 problems you will run into most often: missing topics, type mismatches, QoS incompatibilities, Domain ID conflicts, DDS discovery issues, container networking, timestamp/clock problems, TF errors, and permissions. Each section gives the commands to confirm (or rule out) that cause before moving to the next.
Overview
Most ROS 2 issues fall into a small number of categories, and most of them are diagnosable from the command line in under a minute once you know where to look. Work through the relevant section below in order — top to bottom within a section — rather than guessing.
Why It Matters
"It doesn't work" is not actionable. A short, repeatable diagnostic sequence turns a vague symptom into a specific, fixable cause, and is faster than trial-and-error changes to code or configuration.
Missing Topics
A node, topic, service, or action you expect to see does not appear anywhere.
- Confirm the environment is sourced in the terminal you are checking from:
See CLI Basics.printenv ROS_DISTROwhich ros2
- Confirm the node is actually running (not crashed on startup):
If it's missing, check the terminal that launched it for a stack trace or error.ros2 node list
- Confirm
ROS_DOMAIN_IDmatches between the terminal running the node and the terminal running the CLI — see Domain ID below. - Confirm the fully resolved topic name and namespace:
A relative topic name used in code may resolve to a different fully qualified name depending on the node's namespace.ros2 topic list
- Check for a QoS mismatch if the topic is listed but
echoshows nothing — see QoS Mismatch below.
Type Mismatch
Two nodes appear to use the "same" topic or service name but cannot exchange data, or a CLI call reports a type error.
ros2 topic type /some_topic
ros2 interface show <package>/msg/<Type>
- The package name and type name must match exactly on both ends (e.g.,
std_msgs/msg/Stringvs. a custom message with the same field names is not the same type). - If you built a custom interface package, confirm it was rebuilt and the overlay re-sourced after any
.msg/.srv/.actionfile change — stale generated code is a common cause of "it used to work." - For services/actions, check the request/response or goal/result/feedback shape with
ros2 interface show, and compare field-by-field with what the client is sending.
QoS Mismatch
A publisher and subscriber both exist on the same topic, but no data flows between them.
ros2 topic info /some_topic -v
This prints the QoS profile (reliability, durability, history, depth) for every publisher and subscriber on the topic. Common incompatibilities:
| Setting | Mismatch that breaks delivery |
|---|---|
| Reliability | Publisher BEST_EFFORT with subscriber RELIABLE (subscriber requests a guarantee the publisher does not offer) |
| Durability | Publisher VOLATILE with subscriber TRANSIENT_LOCAL (subscriber expects late-joining delivery of the last message; publisher does not keep one) |
The fix is to make the publisher and subscriber QoS profiles compatible. They do not need to be identical; the publisher must offer QoS guarantees that satisfy the subscriber's requested profile.
Domain ID
Nodes that should see each other do not, even on the same network, with no other obvious cause.
printenv ROS_DOMAIN_ID
- Nodes that should participate in the same ROS 2 DDS domain normally need the same
ROS_DOMAIN_ID(default0if unset). Matching the Domain ID is necessary for ordinary discovery, but it does not guarantee communication if network, middleware, firewall, or discovery settings are incompatible. - Advantech Robotic Suite provides a helper script for changing it consistently; see ROS 2 Domain ID.
- Check both the host and any container shells independently — sourcing a container does not guarantee it inherited the host's environment variable.
DDS Discovery
Nodes are on the same Domain ID but still cannot see each other, especially across machines or over Wi-Fi/VPN links.
- Multicast-based discovery (the default for most RMW/DDS implementations) can be blocked by network configuration, firewalls, or certain virtual/VPN network adapters. Confirm basic connectivity first (e.g.,
ping) between the machines involved. - Check which RMW implementation is active — this changes discovery behavior and available tuning options:
printenv RMW_IMPLEMENTATION
ros2 doctorruns several baseline environment and network checks and is a reasonable first step:ros2 doctor --report- When nodes are split across multiple machines, confirm firewall rules allow the DDS traffic (ports and protocol depend on the RMW implementation in use — check that implementation's documentation rather than assuming a specific port range applies universally).
Containers
Advantech Robotic Suite runs ROS 2 inside containers on some platforms; container boundaries introduce their own discovery and environment pitfalls.
- Confirm the container's network mode allows the DDS discovery traffic it needs (host networking is the simplest configuration for local discovery; bridged networking often requires extra configuration).
- Environment variables (
ROS_DOMAIN_ID,RMW_IMPLEMENTATION) set on the host are not automatically visible inside a container unless explicitly passed through or re-sourced inside the container shell — check both sides independently:docker exec -it <container_name> bash -c 'printenv ROS_DOMAIN_ID' - If a node inside a container cannot see a node on the host (or in a different container), first confirm they use the same Domain ID and network mode before investigating anything more complex.
Timestamps and Clock
Time-dependent behavior (TF lookups, message filtering, synchronized playback) misbehaves.
- Confirm whether the nodes involved expect simulated time. If
use_sim_timeistrueon a node but nothing publishes/clock, that node's clock will not advance as expected. See Rosbag. - Confirm system clocks are reasonably synchronized across machines if timestamps are compared across a distributed system — large clock skew produces symptoms that look like TF or QoS bugs.
- For "extrapolation into the future/past" TF errors, see the TF2 section below.
TF Issues
See TF2 for the full explanation of frames and transforms. Quick diagnostic sequence:
ros2 run tf2_ros tf2_echo <source_frame> <target_frame>
ros2 run tf2_tools view_frames
- "Frame does not exist" — nothing has published a transform for that frame ID yet; check spelling and confirm the publishing node is running.
- "Lookup would require extrapolation" — the requested timestamp is outside TF2's retained buffer; request the latest available transform instead of an explicit historical stamp unless that history is actually required.
- RobotModel is frozen, broken, or jittering in RViz — check for missing or conflicting TF, timestamp or simulated-time problems, and missing or inconsistent
/joint_states. During bag playback, also check whether recorded TF overlaps with transforms generated by live nodes such asrobot_state_publisher.
Permissions
Commands fail with permission-denied errors rather than ROS 2-specific errors.
- Executable bit missing on a script-based node:
chmod +xthe file (Python entry points installed viasetup.py/colcondo not usually need this, but manually invoked scripts sometimes do). - Device access (serial ports, USB cameras, CAN interfaces) commonly requires the user to be in a specific group (e.g.,
dialout) or requiresudevrules — check the specific hardware driver's documentation for the exact group or rule required. - Container volume/user mismatches: files created inside a container may be owned by a different UID than your host user, which can block editing or deleting them from the host afterward.
rosdeppermission errors —rosdep inittypically requires elevated privileges because it creates system-level configuration:Run rosdep update as the normal user:sudo rosdep initrosdep update
Useful Commands
# Environment
printenv ROS_DISTRO
printenv ROS_DOMAIN_ID
printenv RMW_IMPLEMENTATION
ros2 doctor --report
# Graph
ros2 node list
ros2 topic list -t
ros2 topic info <topic> -v
ros2 service list -t
ros2 action list -t
# TF
ros2 run tf2_ros tf2_echo <source_frame> <target_frame>
ros2 run tf2_tools view_frames
Key Takeaways
- Work through symptoms as categories (missing topics, type mismatch, QoS, Domain ID, DDS discovery, containers, timestamps, TF, permissions), not as one-off guesses.
ros2 topic info -vandros2 doctor --reportresolve a large fraction of "why isn't this working" questions on their own.- Nodes that should discover each other must normally use the same
ROS_DOMAIN_ID. Their RMW implementations and discovery/transport settings must also be compatible; using the same RMW implementation can simplify troubleshooting, but it is not an absolute requirement. - TF and playback problems can result from missing transforms, timing issues, or conflicting TF authorities. During bag playback, ensure that overlapping transforms are not produced by multiple sources.
Next
Return to the ROS 2 learning map if you have resolved your issue, or revisit ROS 2 Domain ID, TF2, or Rosbag for deeper detail on those specific topics.