diff --git a/common/udpnat/conn_wait.go b/common/udpnat/conn_wait.go
index 2e6d741..968d557 100644
--- a/common/udpnat/conn_wait.go
+++ b/common/udpnat/conn_wait.go
@@ -2,6 +2,7 @@ package udpnat
 
 import (
 	"io"
+	"os"
 
 	"github.com/sagernet/sing/common/buf"
 	M "github.com/sagernet/sing/common/metadata"
@@ -34,5 +35,7 @@ func (c *conn) WaitReadPacket() (buffer *buf.Buffer, destination M.Socksaddr, er
 		return
 	case <-c.ctx.Done():
 		return nil, M.Socksaddr{}, io.ErrClosedPipe
+	case <-c.readDeadline.Wait():
+		return nil, M.Socksaddr{}, os.ErrDeadlineExceeded
 	}
 }
diff --git a/common/udpnat/service.go b/common/udpnat/service.go
index 100a390..8dd88c5 100644
--- a/common/udpnat/service.go
+++ b/common/udpnat/service.go
@@ -13,6 +13,7 @@ import (
 	E "github.com/sagernet/sing/common/exceptions"
 	M "github.com/sagernet/sing/common/metadata"
 	N "github.com/sagernet/sing/common/network"
+	"github.com/sagernet/sing/common/pipe"
 )
 
 type Handler interface {
@@ -116,6 +117,7 @@ type conn struct {
 	localAddr       M.Socksaddr
 	remoteAddr      M.Socksaddr
 	source          N.PacketWriter
+	readDeadline    pipe.Deadline
 	readWaitOptions N.ReadWaitOptions
 }
 
@@ -127,6 +129,8 @@ func (c *conn) ReadPacket(buffer *buf.Buffer) (addr M.Socksaddr, err error) {
 		return p.destination, err
 	case <-c.ctx.Done():
 		return M.Socksaddr{}, io.ErrClosedPipe
+	case <-c.readDeadline.Wait():
+		return M.Socksaddr{}, os.ErrDeadlineExceeded
 	}
 }
 
@@ -159,7 +163,8 @@ func (c *conn) SetDeadline(t time.Time) error {
 }
 
 func (c *conn) SetReadDeadline(t time.Time) error {
-	return os.ErrInvalid
+	c.readDeadline.Set(t)
+	return nil
 }
 
 func (c *conn) SetWriteDeadline(t time.Time) error {