Status code · Connection

BadEndpointUrlInvalid

BadEndpoint URL

BadEndpointUrlInvalid means the endpoint URL you supplied is not one the server accepts - wrong scheme, wrong host, wrong port, or an endpoint the server does not advertise. Call GetEndpoints with security None first and connect using an EndpointUrl the server actually returned.

Defined behaviour: The server does not recognise the EndpointUrl specified, or the URL is not a valid endpoint URL for this application. (our description of the condition this code reports)

What you actually see

The connection fails before any certificate or user prompt, usually within a second, with the client reporting the URL rather than a network or security problem.

Why it happens

  • The URL was typed or templated wronglyopc.tcp:// with one slash, a missing port, a trailing space, http:// instead of opc.tcp://, or a copy-paste from documentation that used a different path. The transport scheme decides the transport profile, so opc.tcp, opc.https and opc.wss are not interchangeable even against the same host.
  • The endpoint is not one the server advertisesA server returns a fixed set of EndpointDescriptions. Asking for an endpoint with a security policy or message security mode it does not offer, or for a second application hosted on the same port, is refused. Guessing the URL never works; discovery does.
  • The advertised EndpointUrl is not reachable from where you areThe server builds its EndpointUrl from its own configured hostname, which may be an internal name, a container hostname, or a Docker bridge address. A client that blindly connects to the returned URL fails even though discovery on the dialled address worked.
  • Wrong transport for the portPort 4840 is the registered opc.tcp and Local Discovery Server port; 4843 is the registered default for secure WebSockets and DTLS in the reference stack. Pointing opc.tcp at an HTTPS or WebSocket listener, or the reverse, produces a URL-level rejection.
  • Connecting to the LDS instead of the serverThe Local Discovery Server on 4840 answers FindServers and GetEndpoints, but it does not host your application's session endpoints. Clients that treat the discovery URL as the session URL fail here.

How to fix it

In diagnostic order: work down, do not skip ahead.

  1. Prove TCP reachability firstRun nc -vz plc01 4840 or Test-NetConnection plc01 -Port 4840. A refused or timed-out socket is a different problem - see BadConnectionRejected. Only continue once the port answers.
  2. Call GetEndpoints with security NoneUse the discovery endpoint on the address you dialled, for example opc.tcp://opcua.umati.app:4840. This is the second step of the standard diagnostic order and it returns the authoritative list.
  3. Inspect the returned EndpointDescriptionsNote EndpointUrl, SecurityPolicyUri, SecurityMode, TransportProfileUri and UserIdentityTokens for each. Choose one exactly, and copy the EndpointUrl verbatim rather than constructing it.
  4. Decide whether to trust the returned URLIf the returned EndpointUrl uses a hostname you cannot resolve, either fix the server's advertised hostname, add a hosts entry, or use a client that substitutes the URL it dialled. UaExpert offers this substitution explicitly.
  5. Only then attempt the secure sessionConnect with the chosen endpoint, its security policy and mode, and the matching user identity token. Attempting a secure session before the endpoint list is confirmed confuses URL problems with certificate problems.

Where it shows up, by tool and stack

Tool / stackWhat to do there
UaExpertAdd Server by URL, then expand the discovered node to see the real endpoints. UaExpert can replace the server-supplied hostname with the one you dialled, which is the quickest workaround for a misconfigured advertised hostname.
opcua-commanderRun it with the endpoint URL on the command line; it lists endpoints before connecting, which makes it a fast way to check what a server actually offers from a terminal.
asyncua (Python)Client(url) then await client.connect() performs discovery and endpoint selection. client.get_endpoints() alone, without connecting, is the minimal reproduction for this class of fault.
node-opcuaThe bundled command-line tools will dump endpoints for a URL. endpoint_must_exist=false in the client options makes the client use the URL you gave rather than the one the server returned - useful with NAT and containers.
OPC PublisherEndpointUrl in the published-nodes configuration must match an endpoint the server advertises, including the path. A mismatch shows as a connection that never establishes and no telemetry for that entry.
DockerA server in a container often advertises the container hostname. Set the server's application hostname explicitly to the name or address clients use, or run with host networking during commissioning.

What it looks like in the log

Connect failed: BadEndpointUrlInvalid for opc.tcp://plc01:4840/UA/Server
GetEndpoints returned 4 endpoints; none matches the requested SecurityPolicy None with mode SignAndEncrypt
Server advertised endpointUrl opc.tcp://a1b2c3d4e5f6:4840 which does not resolve from this client

Confirm the fix

Connect using an EndpointUrl copied verbatim from GetEndpoints and confirm a session is created. Then confirm the same URL works from a second host to rule out a client-local hosts entry.

Stop it happening again

Store endpoint URLs in configuration as discovered values, never hand-typed, and set the server's advertised hostname deliberately at commissioning - especially in containers and behind NAT.

Stuck on more than one of these? The troubleshooting clinic works through broken configurations end to end, on camera.

Troubleshooting clinic →

Last verified 7 September 2026 against OPC UA 1.05.07. OPC UA Connect is an educational resource and is not affiliated with the OPC Foundation.

Free download
OPC UA Status Code Diagnostic Tree
A 15-page diagnostic reference grouping every normative status code by what actually went wrong: with the first action for each, and the four questions that resolve most faults before you read a single code.
Get the free diagnostic tree →
Free, no course, no login