diff --git a/cmd/sentry/sentry/downloader.go b/cmd/sentry/sentry/downloader.go
index cd617ad94098e87148d066ec358b8990c67f86db..77542a5d04144f9a62de73ed6ca7b512bd5dd64c 100644
--- a/cmd/sentry/sentry/downloader.go
+++ b/cmd/sentry/sentry/downloader.go
@@ -555,7 +555,7 @@ func (cs *ControlServerImpl) newBlock66(ctx context.Context, inreq *proto_sentry
 		return fmt.Errorf("newBlock66: %w", err)
 	}
 
-	if segments, penalty, err := cs.Hd.SingleHeaderAsSegment(headerRaw, request.Block.Header()); err == nil {
+	if segments, penalty, err := cs.Hd.SingleHeaderAsSegment(headerRaw, request.Block.Header(), true /* penalizePoSBlocks */); err == nil {
 		if penalty == headerdownload.NoPenalty {
 			cs.Hd.ProcessSegment(segments[0], true /* newBlock */, ConvertH512ToPeerID(inreq.PeerId)) // There is only one segment in this case
 		} else {
diff --git a/turbo/stages/bodydownload/body_algos.go b/turbo/stages/bodydownload/body_algos.go
index f8b4cac250f1c86160cb35190ca198123a6d627a..30a1caf523f8fa26924a4794faab66bba921f2c1 100644
--- a/turbo/stages/bodydownload/body_algos.go
+++ b/turbo/stages/bodydownload/body_algos.go
@@ -133,12 +133,13 @@ func (bd *BodyDownload) RequestMoreBodies(tx kv.RwTx, blockReader interfaces.Ful
 				bd.deliveriesB[blockNum-bd.requestedLow] = block.RawBody()
 
 				// Calculate the TD of the block (it's not imported yet, so block.Td is not valid)
-				var td *big.Int
 				if parent, err := rawdb.ReadTd(tx, block.ParentHash(), block.NumberU64()-1); err != nil {
 					log.Error("Failed to ReadTd", "err", err, "number", block.NumberU64()-1, "hash", block.ParentHash())
 				} else if parent != nil {
-					td = new(big.Int).Add(block.Difficulty(), parent)
-					go blockPropagator(context.Background(), block, td)
+					if block.Difficulty().Sign() != 0 { // don't propagate proof-of-stake blocks
+						td := new(big.Int).Add(block.Difficulty(), parent)
+						go blockPropagator(context.Background(), block, td)
+					}
 				} else {
 					log.Error("Propagating dangling block", "number", block.Number(), "hash", hash)
 				}
diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go
index 9deab0df1b63629c46a48e23e948714b98bcd388..ec7607b73bbece4d79d84b03cd142e97bad791eb 100644
--- a/turbo/stages/headerdownload/header_algos.go
+++ b/turbo/stages/headerdownload/header_algos.go
@@ -131,7 +131,7 @@ func (hd *HeaderDownload) childParentValid(child, parent *types.Header) (bool, P
 }
 
 // SingleHeaderAsSegment converts message containing 1 header into one singleton chain segment
-func (hd *HeaderDownload) SingleHeaderAsSegment(headerRaw []byte, header *types.Header) ([]ChainSegment, Penalty, error) {
+func (hd *HeaderDownload) SingleHeaderAsSegment(headerRaw []byte, header *types.Header, penalizePoSBlocks bool) ([]ChainSegment, Penalty, error) {
 	hd.lock.RLock()
 	defer hd.lock.RUnlock()
 
@@ -139,6 +139,9 @@ func (hd *HeaderDownload) SingleHeaderAsSegment(headerRaw []byte, header *types.
 	if _, bad := hd.badHeaders[headerHash]; bad {
 		return nil, BadBlockPenalty, nil
 	}
+	if penalizePoSBlocks && header.Difficulty.Sign() == 0 {
+		return nil, NewBlockGossipAfterMergePenalty, nil
+	}
 	h := ChainSegmentHeader{
 		Header:    header,
 		HeaderRaw: headerRaw,
@@ -1356,7 +1359,7 @@ func (hd *HeaderDownload) AddMinedHeader(header *types.Header) error {
 	if err := header.EncodeRLP(buf); err != nil {
 		return err
 	}
-	segments, _, err := hd.SingleHeaderAsSegment(buf.Bytes(), header)
+	segments, _, err := hd.SingleHeaderAsSegment(buf.Bytes(), header, false /* penalizePoSBlocks */)
 	if err != nil {
 		return err
 	}
diff --git a/turbo/stages/headerdownload/header_data_struct.go b/turbo/stages/headerdownload/header_data_struct.go
index d2da1eebfac6cec4ec0de563ee5b3d30bc0902c6..619d8f42883ffdf7df17854cc0efdcf5485d6873 100644
--- a/turbo/stages/headerdownload/header_data_struct.go
+++ b/turbo/stages/headerdownload/header_data_struct.go
@@ -180,6 +180,7 @@ const (
 	TooFarFuturePenalty
 	TooFarPastPenalty
 	AbandonedAnchorPenalty
+	NewBlockGossipAfterMergePenalty
 )
 
 type PeerPenalty struct {
@@ -355,6 +356,8 @@ func (p Penalty) String() string {
 		return "TooFarFuture"
 	case TooFarPastPenalty:
 		return "TooFarPast"
+	case NewBlockGossipAfterMergePenalty:
+		return "NewBlockGossipAfterMerge"
 	default:
 		return fmt.Sprintf("Unknown(%d)", p)
 	}
diff --git a/turbo/stages/headerdownload/header_test.go b/turbo/stages/headerdownload/header_test.go
index 8c16ebac71afeaa1ec051a258bde9405fcd32731..59aec92e1601115393633e625a5885f415bad85f 100644
--- a/turbo/stages/headerdownload/header_test.go
+++ b/turbo/stages/headerdownload/header_test.go
@@ -166,7 +166,7 @@ func TestSingleHeaderAsSegment(t *testing.T) {
 	var h types.Header
 	h.Number = big.NewInt(5)
 	headerRaw, _ := rlp.EncodeToBytes(h)
-	if chainSegments, penalty, err := hd.SingleHeaderAsSegment(headerRaw, &h); err == nil {
+	if chainSegments, penalty, err := hd.SingleHeaderAsSegment(headerRaw, &h, false /* penalizePoSBlocks */); err == nil {
 		if penalty != NoPenalty {
 			t.Errorf("unexpected penalty: %s", penalty)
 		}
@@ -185,7 +185,7 @@ func TestSingleHeaderAsSegment(t *testing.T) {
 
 	// Same header with a bad hash
 	hd.ReportBadHeader(h.Hash())
-	if chainSegments, penalty, err := hd.SingleHeaderAsSegment(headerRaw, &h); err == nil {
+	if chainSegments, penalty, err := hd.SingleHeaderAsSegment(headerRaw, &h, false /* penalizePoSBlocks */); err == nil {
 		if penalty != BadBlockPenalty {
 			t.Errorf("expected BadBlock penalty, got %s", penalty)
 		}