Error message: Error in plugin: connect failed: dial tcp 192.168.65.254:5215: connect: connection refused

Good evening,
I am currently trying to build a Docker Compose Stack with Grafana, InfluxDB and Telegraf. For testing purposes, a colleague wrote me a simple Pyhton OPC UA server that should output some data. Unfortunately, I keep getting the following error when I check the telegraf logs:
telegraf | 2025-07-07T16:46:10Z E! [inputs.opcua] Error in plugin: connect failed: dial tcp 192.168.65.254:5215: connect: connection refused

I have already created a rule in the firewall and allowed the connection to the port… Unfortunately, that didn’t help. And therefore no data arrives in InfluxDB…

Here is my telegraf.conf:

[agent]
  interval = "10s"
  round_interval = true

[[inputs.opcua]]
  endpoint = "opc.tcp://host.docker.internal:5215/"
  

nodes = [
  { name = "hp_pressure", namespace = "2", identifier_type = "s", identifier = "hp_p" },
  { name = "hp_pressure_up", namespace = "2", identifier_type = "s", identifier = "hp_p_up" },
  { name = "hp_pressure_lo", namespace = "2", identifier_type = "s", identifier = "hp_p_lo" },

  { name = "fuel_pressure", namespace = "2", identifier_type = "s", identifier = "f_p" },
  { name = "fuel_pressure_up", namespace = "2", identifier_type = "s", identifier = "f_p_up" },
  { name = "fuel_pressure_lo", namespace = "2", identifier_type = "s", identifier = "f_p_lo" },

  { name = "lox_pressure", namespace = "2", identifier_type = "s", identifier = "lox_p" },
  { name = "lox_pressure_up", namespace = "2", identifier_type = "s", identifier = "lox_p_up" },
  { name = "lox_pressure_lo", namespace = "2", identifier_type = "s", identifier = "lox_p_lo" }
]

[[outputs.influxdb_v2]]
  urls = ["http://influxdb:8086"]
  token = "Removed"
  organization = "Removed"
  bucket = "Removed"

Here the Server:

# This starts an OPCUA server with some nodes that generate data based on their names

import asyncio
import logging
import random
import math

from asyncua import Server, ua, Node
from asyncua.ua import AttributeIds, LocalizedText, DataValue, DataTypeDefinition

def idFromString(ns: int, id: str):
    return f"ns={ns};s={id}"

async def main():
    server = Server()
    await server.init()
    server.set_endpoint("opc.tcp://[::]:5215/")

    idx = await server.register_namespace("WARR")

    obj_mcs = await server.nodes.objects.add_object(idFromString(idx, "mcs"), "mcs")

    obj_systems = await obj_mcs.add_object(idFromString(idx, "sys"), "systems")
    
    obj_hp = await obj_systems.add_object(idFromString(idx, "hp"), "high_pressure")
    obj_fuel = await obj_systems.add_object(idFromString(idx, "f"), "fuel")
    obj_lox = await obj_systems.add_object(idFromString(idx, "lox"), "liquid_oxygen")

    await obj_hp.add_variable(idFromString(idx, "hp_p"), "hp_pressure", 250.0)
    await obj_hp.add_variable(idFromString(idx, "hp_p_up"), "hp_pressure_up", 310.0)
    await obj_hp.add_variable(idFromString(idx, "hp_p_lo"), "hp_pressure_lo", 0.0)

    await obj_lox.add_variable(idFromString(idx, "lox_p"), "lox_pressure", 10.0)
    await obj_lox.add_variable(idFromString(idx, "lox_p_up"), "lox_pressure_up", 60.0)
    await obj_lox.add_variable(idFromString(idx, "lox_p_lo"), "lox_pressure_lo", 0.0)

    await obj_fuel.add_variable(idFromString(idx, "f_p"), "fuel_pressure", 15.0)
    await obj_fuel.add_variable(idFromString(idx, "f_p_up"), "fuel_pressure_up", 60.0)
    await obj_fuel.add_variable(idFromString(idx, "f_p_lo"), "fuel_pressure_lo", 0.0)

    async with server:
        while True:
            await asyncio.sleep(0.01)



if __name__ == "__main__":
    asyncio.run(main(), debug=True)

I hope someone can help me :slight_smile:

Looking at your error, the issue is likely related to network connectivity between your Docker containers and the OPC UA server. The error dial tcp 192.168.65.254:5215: connect: connection refused suggests that Telegraf can’t reach your OPC UA server.

From inside the Telegraf container, test if you can reach the OPC UA server:

# Get into the telegraf container
docker exec -it <telegraf_container_name> sh

# Test connection (if telnet is available)
telnet host.docker.internal 5215

# Or test with nc if available
nc -zv host.docker.internal 5215

Try this modified server code with better error handling and explicit IPv4 binding:

import asyncio
import logging
import socket

from asyncua import Server, ua

# Enable debug logging
logging.basicConfig(level=logging.DEBUG)

def idFromString(ns: int, id: str):
    return f"ns={ns};s={id}"

async def main():
    server = Server()
    await server.init()
    
    # Bind explicitly to IPv4 all interfaces
    server.set_endpoint("opc.tcp://0.0.0.0:5215/")
    
    # Get and print the actual IP address
    hostname = socket.gethostname()
    local_ip = socket.gethostbyname(hostname)
    print(f"Server starting on: opc.tcp://{local_ip}:5215/")
    print(f"Also accessible via: opc.tcp://0.0.0.0:5215/")

    idx = await server.register_namespace("WARR")

    # Your existing node setup...
    obj_mcs = await server.nodes.objects.add_object(idFromString(idx, "mcs"), "mcs")
    obj_systems = await obj_mcs.add_object(idFromString(idx, "sys"), "systems")
    
    obj_hp = await obj_systems.add_object(idFromString(idx, "hp"), "high_pressure")
    obj_fuel = await obj_systems.add_object(idFromString(idx, "f"), "fuel")
    obj_lox = await obj_systems.add_object(idFromString(idx, "lox"), "liquid_oxygen")

    await obj_hp.add_variable(idFromString(idx, "hp_p"), "hp_pressure", 250.0)
    await obj_hp.add_variable(idFromString(idx, "hp_p_up"), "hp_pressure_up", 310.0)
    await obj_hp.add_variable(idFromString(idx, "hp_p_lo"), "hp_pressure_lo", 0.0)

    await obj_lox.add_variable(idFromString(idx, "lox_p"), "lox_pressure", 10.0)
    await obj_lox.add_variable(idFromString(idx, "lox_p_up"), "lox_pressure_up", 60.0)
    await obj_lox.add_variable(idFromString(idx, "lox_p_lo"), "lox_pressure_lo", 0.0)

    await obj_fuel.add_variable(idFromString(idx, "f_p"), "fuel_pressure", 15.0)
    await obj_fuel.add_variable(idFromString(idx, "f_p_up"), "fuel_pressure_up", 60.0)
    await obj_fuel.add_variable(idFromString(idx, "f_p_lo"), "fuel_pressure_lo", 0.0)

    print("Server started and ready for connections...")
    
    async with server:
        while True:
            await asyncio.sleep(1)

if __name__ == "__main__":
    asyncio.run(main())