diff --git a/p2p/dial.go b/p2p/dial.go
index d190e866af2904f9a000fc69b83f2ace7790281c..d36d6655019aedcfa997511677a2c51479df9e59 100644
--- a/p2p/dial.go
+++ b/p2p/dial.go
@@ -78,6 +78,7 @@ var (
 	errAlreadyConnected = errors.New("already connected")
 	errRecentlyDialed   = errors.New("recently dialed")
 	errNotWhitelisted   = errors.New("not contained in netrestrict whitelist")
+	errNoPort           = errors.New("node does not provide TCP port")
 )
 
 // dialer creates outbound connections and submits them into Server.
@@ -388,6 +389,12 @@ func (d *dialScheduler) checkDial(n *enode.Node) error {
 	if n.ID() == d.self {
 		return errSelf
 	}
+	if n.IP() != nil && n.TCP() == 0 {
+		// This check can trigger if a non-TCP node is found
+		// by discovery. If there is no IP, the node is a static
+		// node and the actual endpoint will be resolved later in dialTask.
+		return errNoPort
+	}
 	if _, ok := d.dialing[n.ID()]; ok {
 		return errAlreadyDialing
 	}
@@ -474,15 +481,13 @@ type dialError struct {
 }
 
 func (t *dialTask) run(d *dialScheduler) {
-	if t.dest.Incomplete() {
-		if !t.resolve(d) {
-			return
-		}
+	if t.needResolve() && !t.resolve(d) {
+		return
 	}
 
 	err := t.dial(d, t.dest)
 	if err != nil {
-		// Try resolving the ID of static nodes if dialing failed.
+		// For static nodes, resolve one more time if dialing fails.
 		if _, ok := err.(*dialError); ok && t.flags&staticDialedConn != 0 {
 			if t.resolve(d) {
 				t.dial(d, t.dest)
@@ -491,6 +496,10 @@ func (t *dialTask) run(d *dialScheduler) {
 	}
 }
 
+func (t *dialTask) needResolve() bool {
+	return t.flags&staticDialedConn != 0 && t.dest.IP() == nil
+}
+
 // resolve attempts to find the current endpoint for the destination
 // using discovery.
 //
diff --git a/p2p/discover/v4_udp.go b/p2p/discover/v4_udp.go
index 6af05f93ddc742d06c6db1433e508b577677ad5d..cc395d8f0db66cfa19e325fd50ed9417f8f3cc83 100644
--- a/p2p/discover/v4_udp.go
+++ b/p2p/discover/v4_udp.go
@@ -169,7 +169,7 @@ func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) rpcEndpoint {
 
 func (t *UDPv4) nodeFromRPC(sender *net.UDPAddr, rn rpcNode) (*node, error) {
 	if rn.UDP <= 1024 {
-		return nil, errors.New("low port")
+		return nil, errLowPort
 	}
 	if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil {
 		return nil, err
diff --git a/p2p/simulations/adapters/types.go b/p2p/simulations/adapters/types.go
index ec22b712c351a7395fffb482eab4f58e8ba3aa37..498723d1ac264b244b8c5391897d26786925f839 100644
--- a/p2p/simulations/adapters/types.go
+++ b/p2p/simulations/adapters/types.go
@@ -300,5 +300,5 @@ func (n *NodeConfig) initEnode(ip net.IP, tcpport int, udpport int) error {
 }
 
 func (n *NodeConfig) initDummyEnode() error {
-	return n.initEnode(net.IPv4(127, 0, 0, 1), 0, 0)
+	return n.initEnode(net.IPv4(127, 0, 0, 1), int(n.Port), 0)
 }