--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -38,7 +_,7 @@
     private static final boolean DEFAULT_EXTENDING = false;
     private static final boolean DEFAULT_SOURCE = false;
     private BlockState movedState = DEFAULT_BLOCK_STATE;
-    private Direction direction;
+    private Direction direction = Direction.DOWN; // Paper - default to first value to avoid NPE
     private boolean extending = false;
     private boolean isSourcePiston = false;
     private static final ThreadLocal<Direction> NOCLIP = ThreadLocal.withInitial(() -> null);
@@ -309,7 +_,7 @@
                 if (level.getBlockState(pos).is(Blocks.MOVING_PISTON)) {
                     BlockState blockState = Block.updateFromNeighbourShapes(blockEntity.movedState, level, pos);
                     if (blockState.isAir()) {
-                        level.setBlock(pos, blockEntity.movedState, 340);
+                        level.setBlock(pos, blockEntity.movedState, io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPistonDuplication ? 340 : (340 | Block.UPDATE_CLIENTS)); // Paper - fix a variety of piston desync dupes; force notify (flag 2), it's possible the set type by the piston block (which doesn't notify) set this block to air
                         Block.updateOrDestroy(blockEntity.movedState, blockState, level, pos, 3);
                     } else {
                         if (blockState.hasProperty(BlockStateProperties.WATERLOGGED) && blockState.getValue(BlockStateProperties.WATERLOGGED)) {
