diff --git a/dapps/valuetransfers/packages/tangle/tangle.go b/dapps/valuetransfers/packages/tangle/tangle.go
index 7c91dec1711e6dd251325a46b6987a493af1cd99..15b192b9e28ee01fda6d36a261fa940017a39fe9 100644
--- a/dapps/valuetransfers/packages/tangle/tangle.go
+++ b/dapps/valuetransfers/packages/tangle/tangle.go
@@ -21,6 +21,12 @@ import (
 	"github.com/iotaledger/goshimmer/packages/binary/storageprefix"
 )
 
+var (
+	// ErrTransactionDoesNotSpendAllFunds is returned if a transaction does not spend all of its inputs.
+	ErrTransactionDoesNotSpendAllFunds = errors.New("transaction does not spend all funds from inputs")
+	// ErrInvalidTransactionSignature is returned if the signature of a transaction is invalid.
+	ErrInvalidTransactionSignature     = errors.New("invalid transaction signatures")
+)
 // Tangle represents the value tangle that consists out of value payloads.
 // It is an independent ontology, that lives inside the tangle.
 type Tangle struct {
@@ -1577,6 +1583,27 @@ func (tangle *Tangle) getCachedOutputsFromTransactionInputs(tx *transaction.Tran
 	return
 }
 
+// ValidateTransactionToAttach checks that the given transaction spends all funds from its inputs and
+// that its the signature is valid.
+func (tangle *Tangle) ValidateTransactionToAttach(tx *transaction.Transaction) (err error) {
+	_, cachedInputs, consumedBalances, _, err := tangle.retrieveConsumedInputDetails(tx)
+	defer cachedInputs.Release()
+	if err != nil {
+		return
+	}
+	if !tangle.checkTransactionOutputs(consumedBalances, tx.Outputs()) {
+		err = ErrTransactionDoesNotSpendAllFunds
+		return
+	}
+
+	if !tx.SignaturesValid() {
+		err = ErrInvalidTransactionSignature
+		return
+	}
+	return
+}
+
+// retrieveConsumedInputDetails retrieves the details of the consumed inputs of a transaction.
 func (tangle *Tangle) retrieveConsumedInputDetails(tx *transaction.Transaction) (inputsSolid bool, cachedInputs CachedOutputs, consumedBalances map[balance.Color]int64, consumedBranches branchmanager.BranchIds, err error) {
 	cachedInputs = tangle.getCachedOutputsFromTransactionInputs(tx)
 	consumedBalances = make(map[balance.Color]int64)
diff --git a/dapps/valuetransfers/packages/transaction/transaction.go b/dapps/valuetransfers/packages/transaction/transaction.go
index 3b234bdf0bec0bff067f85aa5ca4fae2b3e7bb5b..760ded1db4a41edd801eb03722a6f0aea8d105fa 100644
--- a/dapps/valuetransfers/packages/transaction/transaction.go
+++ b/dapps/valuetransfers/packages/transaction/transaction.go
@@ -15,6 +15,11 @@ import (
 	"github.com/iotaledger/goshimmer/dapps/valuetransfers/packages/address/signaturescheme"
 )
 
+var (
+	// ErrMaxDataPayloadSizeExceeded is returned if the data payload size is exceeded.
+	ErrMaxDataPayloadSizeExceeded = errors.New("maximum data payload size exceeded")
+)
+
 // region IMPLEMENT Transaction ////////////////////////////////////////////////////////////////////////////////////////////
 
 // Transaction represents a value transfer for IOTA. It consists out of a number of inputs, a number of outputs and their
@@ -311,7 +316,7 @@ func (transaction *Transaction) SetDataPayload(data []byte) error {
 	defer transaction.dataPayloadMutex.Unlock()
 
 	if len(data) > MaxDataPayloadSize {
-		return fmt.Errorf("maximum dataPayload size of %d bytes exceeded", MaxDataPayloadSize)
+		return fmt.Errorf("%w: %d", ErrMaxDataPayloadSizeExceeded, MaxDataPayloadSize)
 	}
 	transaction.dataPayload = data
 	return nil
@@ -382,8 +387,7 @@ func (transaction *Transaction) UnmarshalObjectStorageValue(bytes []byte) (consu
 		return
 	}
 	if dataPayloadSize > MaxDataPayloadSize {
-		err = fmt.Errorf("data payload size of %d bytes exceeds maximum limit of %d bytes",
-			dataPayloadSize, MaxDataPayloadSize)
+		err = fmt.Errorf("%w: %d", ErrMaxDataPayloadSizeExceeded, MaxDataPayloadSize)
 		return
 	}
 
diff --git a/packages/binary/drng/subtypes/collectiveBeacon/payload/payload.go b/packages/binary/drng/subtypes/collectiveBeacon/payload/payload.go
index 2c41c2c8d710406aab97aac21fa4c3c9f43ea630..d53be6f1bf2689d305e90a2319f046f665842dd4 100644
--- a/packages/binary/drng/subtypes/collectiveBeacon/payload/payload.go
+++ b/packages/binary/drng/subtypes/collectiveBeacon/payload/payload.go
@@ -1,6 +1,8 @@
 package payload
 
 import (
+	"errors"
+	"fmt"
 	"sync"
 
 	"github.com/iotaledger/hive.go/stringify"
@@ -11,6 +13,11 @@ import (
 	"github.com/iotaledger/hive.go/marshalutil"
 )
 
+var (
+	// ErrMaximumPayloadSizeExceeded is returned if the payload exceeds the maximum size.
+	ErrMaximumPayloadSizeExceeded = errors.New("maximum payload size exceeded")
+)
+
 // Payload is a collective beacon payload.
 type Payload struct {
 	header.Header
@@ -28,6 +35,9 @@ type Payload struct {
 	bytesMutex sync.RWMutex
 }
 
+// MaxCollectiveBeaconPayloadSize defines the maximum size of a collective beacon payload.
+const MaxCollectiveBeaconPayloadSize = 64 * 1024
+
 // New creates a new collective beacon payload.
 func New(instanceID uint32, round uint64, prevSignature, signature, dpk []byte) *Payload {
 	return &Payload{
@@ -41,11 +51,15 @@ func New(instanceID uint32, round uint64, prevSignature, signature, dpk []byte)
 
 // Parse is a wrapper for simplified unmarshaling in a byte stream using the marshalUtil package.
 func Parse(marshalUtil *marshalutil.MarshalUtil) (*Payload, error) {
-	if payload, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return FromBytes(data) }); err != nil {
-		return &Payload{}, err
-	} else {
-		return payload.(*Payload), nil
+	unmarshalledPayload, err := marshalUtil.Parse(func(data []byte) (interface{}, int, error) { return FromBytes(data) })
+	if err != nil {
+		return nil, err
+	}
+	_payload := unmarshalledPayload.(*Payload)
+	if len(_payload.bytes) > MaxCollectiveBeaconPayloadSize {
+		return nil, fmt.Errorf("%w: %d", ErrMaximumPayloadSizeExceeded, MaxCollectiveBeaconPayloadSize)
 	}
+	return _payload, nil
 }
 
 // FromBytes parses the marshaled version of a Payload into an object.
diff --git a/packages/binary/messagelayer/payload/data.go b/packages/binary/messagelayer/payload/data.go
index 9db9cc640b6e9f5114f94a5de8d042e640cc866a..6092956c7f1a7d42f5c6c7b274924d2c68b72038 100644
--- a/packages/binary/messagelayer/payload/data.go
+++ b/packages/binary/messagelayer/payload/data.go
@@ -14,6 +14,9 @@ type Data struct {
 	data        []byte
 }
 
+// MaxDataPayloadSize defines the maximum size of a data payload.
+const MaxDataPayloadSize = 64 * 1024
+
 // NewData creates new data payload.
 func NewData(data []byte) *Data {
 	return &Data{
diff --git a/packages/binary/messagelayer/payload/payload.go b/packages/binary/messagelayer/payload/payload.go
index f70f87578a42015d56bf590921ab93969ab2b5de..a0282c323f6617809ffcfd0cd652a26f742375fb 100644
--- a/packages/binary/messagelayer/payload/payload.go
+++ b/packages/binary/messagelayer/payload/payload.go
@@ -1,9 +1,17 @@
 package payload
 
 import (
+	"errors"
+	"fmt"
+
 	"github.com/iotaledger/hive.go/marshalutil"
 )
 
+var (
+	// ErrMaximumPayloadSizeExceeded is returned if the payload exceeds the maximum size.
+	ErrMaximumPayloadSizeExceeded = errors.New("maximum payload size exceeded")
+)
+
 const (
 	// ObjectName defines the name of the data object.
 	ObjectName = "data"
@@ -45,6 +53,11 @@ func FromBytes(bytes []byte) (result Payload, consumedBytes int, err error) {
 		return
 	}
 
+	if payloadSize > MaxDataPayloadSize {
+		err = fmt.Errorf("%w: %d", ErrMaximumPayloadSizeExceeded, MaxDataPayloadSize)
+		return
+	}
+
 	marshalUtil.ReadSeek(marshalUtil.ReadOffset() - marshalutil.UINT32_SIZE*2)
 	payloadBytes, err := marshalUtil.ReadBytes(int(payloadSize) + 8)
 	if err != nil {
diff --git a/plugins/webapi/data/plugin.go b/plugins/webapi/data/plugin.go
index a13ecce6b59ef7223fc9055afb646367e530cec0..605ad8d8f36f83c78080cf1017dccdadaea336db 100644
--- a/plugins/webapi/data/plugin.go
+++ b/plugins/webapi/data/plugin.go
@@ -1,6 +1,7 @@
 package data
 
 import (
+	"fmt"
 	"net/http"
 	"sync"
 
@@ -44,7 +45,12 @@ func broadcastData(c echo.Context) error {
 		return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
 	}
 
-	//TODO: to check max payload size allowed, if exceeding return an error
+	dataPayload := payload.NewData(request.Data)
+	if len(dataPayload.Bytes()) > payload.MaxDataPayloadSize {
+		err := fmt.Errorf("%w: %d", payload.ErrMaximumPayloadSizeExceeded, payload.MaxDataPayloadSize)
+		return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
+	}
+
 	msg, err := issuer.IssuePayload(payload.NewData(request.Data))
 	if err != nil {
 		return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
diff --git a/plugins/webapi/drng/collectivebeacon/handler.go b/plugins/webapi/drng/collectivebeacon/handler.go
index 591dc4820ca55c0fa61e6f6ba458ed1f9cc10a03..3c21953c861e2b7ef011a772633d2b601a615b2b 100644
--- a/plugins/webapi/drng/collectivebeacon/handler.go
+++ b/plugins/webapi/drng/collectivebeacon/handler.go
@@ -18,11 +18,10 @@ func Handler(c echo.Context) error {
 		return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
 	}
 
-	//TODO: to check max payload size allowed, if exceeding return an error
 	marshalUtil := marshalutil.New(request.Payload)
 	parsedPayload, err := payload.Parse(marshalUtil)
 	if err != nil {
-		return c.JSON(http.StatusBadRequest, Response{Error: "not a valid Collective Beacon payload"})
+		return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
 	}
 
 	msg, err := issuer.IssuePayload(parsedPayload)
diff --git a/plugins/webapi/message/sendPayload.go b/plugins/webapi/message/sendPayload.go
index 159ffe16f0cc7cd0dcc015e39b09cd005fe5955b..cffc572be8a36141ec6f2086edcb1d1d4ec26a3d 100644
--- a/plugins/webapi/message/sendPayload.go
+++ b/plugins/webapi/message/sendPayload.go
@@ -17,11 +17,9 @@ func sendPayload(c echo.Context) error {
 		return c.JSON(http.StatusBadRequest, MsgResponse{Error: err.Error()})
 	}
 
-	//TODO: to check max payload size allowed, if exceeding return an error
-
 	parsedPayload, _, err := payload.FromBytes(request.Payload)
 	if err != nil {
-		return c.JSON(http.StatusBadRequest, MsgResponse{Error: "not a valid payload"})
+		return c.JSON(http.StatusBadRequest, MsgResponse{Error: err.Error()})
 	}
 
 	msg, err := issuer.IssuePayload(parsedPayload)
diff --git a/plugins/webapi/value/sendtransaction/handler.go b/plugins/webapi/value/sendtransaction/handler.go
index 8a65571533c113d60d7a74a9e7108acaa4e34d65..dda59ab8c3d80fbe5c3b69a08dd82254acc81b6c 100644
--- a/plugins/webapi/value/sendtransaction/handler.go
+++ b/plugins/webapi/value/sendtransaction/handler.go
@@ -22,6 +22,11 @@ func Handler(c echo.Context) error {
 		return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
 	}
 
+	err = valuetransfers.Tangle().ValidateTransactionToAttach(tx)
+	if err != nil {
+		return c.JSON(http.StatusBadRequest, Response{Error: err.Error()})
+	}
+
 	// Prepare value payload and send the message to tangle
 	payload := valuetransfers.ValueObjectFactory().IssueTransaction(tx)
 	_, err = issuer.IssuePayload(payload)