diff --git a/src/libs/vlayout/vabstractpiece.cpp b/src/libs/vlayout/vabstractpiece.cpp
index 365038595..eeeae73ff 100644
--- a/src/libs/vlayout/vabstractpiece.cpp
+++ b/src/libs/vlayout/vabstractpiece.cpp
@@ -1419,6 +1419,52 @@ QLineF VAbstractPiece::ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qrea
     return paralel;
 }
 
+//---------------------------------------------------------------------------------------------------------------------
+bool VAbstractPiece::IsAllowanceValid(const QVector<QPointF> &base, const QVector<QPointF> &allowance)
+{
+    if (base.size() < 3 || allowance.size() < 3)
+    {
+        return false; // Not enough data
+    }
+
+    const qreal baseDirection = VPiece::SumTrapezoids(base);
+    const qreal allowanceDirection = VPiece::SumTrapezoids(allowance);
+
+    if (baseDirection >= 0 || allowanceDirection >= 0)
+    {
+        return false; // Wrong direction
+    }
+
+    for (auto i = 0; i < base.count()-1; ++i)
+    {
+        QLineF baseSegment(base.at(i), base.at(i+1));
+        if (baseSegment.isNull())
+        {
+            continue;
+        }
+
+        for (auto j = 0; j < allowance.count()-1; ++j)
+        {
+            QLineF allowanceSegment(allowance.at(j), allowance.at(j+1));
+            if (allowanceSegment.isNull())
+            {
+                continue;
+            }
+
+            QPointF crosPoint;
+            const auto type = baseSegment.intersect(allowanceSegment, &crosPoint);
+            if (type == QLineF::BoundedIntersection && not VFuzzyComparePoints(baseSegment.p1(), crosPoint)
+                    && not VFuzzyComparePoints(baseSegment.p2(), crosPoint))
+            {
+
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
 //---------------------------------------------------------------------------------------------------------------------
 bool VAbstractPiece::IsEkvPointOnLine(const QPointF &iPoint, const QPointF &prevPoint, const QPointF &nextPoint)
 {
diff --git a/src/libs/vlayout/vabstractpiece.h b/src/libs/vlayout/vabstractpiece.h
index c5626fc4f..b5f72af92 100644
--- a/src/libs/vlayout/vabstractpiece.h
+++ b/src/libs/vlayout/vabstractpiece.h
@@ -196,6 +196,7 @@ public:
                                      const VSAPoint &p1Line2, VSAPoint p2Line2, qreal width,
                                      bool *needRollback = nullptr);
     static QLineF           ParallelLine(const VSAPoint &p1, const VSAPoint &p2, qreal width);
+    static bool             IsAllowanceValid(const QVector<QPointF> &base, const QVector<QPointF> &allowance);
 
     template <class T>
     static QVector<T> CorrectPathDistortion(QVector<T> path);
diff --git a/src/libs/vlayout/vbank.cpp b/src/libs/vlayout/vbank.cpp
index 08447e8ac..2789697d3 100644
--- a/src/libs/vlayout/vbank.cpp
+++ b/src/libs/vlayout/vbank.cpp
@@ -32,6 +32,7 @@
 
 #include "../vmisc/diagnostic.h"
 #include "../vmisc/logging.h"
+#include "../vmisc/vabstractapplication.h"
 #include "vlayoutpiece.h"
 
 QT_WARNING_PUSH
@@ -190,10 +191,11 @@ bool VBank::Prepare()
     {
         details[i].SetLayoutWidth(layoutWidth);
         details[i].SetLayoutAllowancePoints();
-        if (not details[i].IsLayoutAllowanceValid())
+        if (not details.at(i).IsLayoutAllowanceValid())
         {
-            qWarning()<< QObject::tr("Piece '%1' may broke a layout. Please, check seam allowance to check how seam "
-                                     "allowance behave.").arg(details[i].GetName());
+            const QString errorMsg = QObject::tr("Piece '%1' has invalid layout allowance. Please, check seam allowance"
+                                                 " to check how seam allowance behave.").arg(details.at(i).GetName());
+            qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg;
         }
 
         const qreal d = details.at(i).Diagonal();
diff --git a/src/libs/vlayout/vlayoutpiece.cpp b/src/libs/vlayout/vlayoutpiece.cpp
index e971df3ff..76a366012 100644
--- a/src/libs/vlayout/vlayoutpiece.cpp
+++ b/src/libs/vlayout/vlayoutpiece.cpp
@@ -254,6 +254,7 @@ VLayoutPiece::~VLayoutPiece()
 VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern)
 {
     QFuture<QVector<QPointF> > futureSeamAllowance = QtConcurrent::run(piece, &VPiece::SeamAllowancePoints, pattern);
+    QFuture<bool> futureSeamAllowanceValid = QtConcurrent::run(piece, &VPiece::IsSeamAllowanceValid, pattern);
     QFuture<QVector<QPointF> > futureMainPath = QtConcurrent::run(piece, &VPiece::MainPathPoints, pattern);
     QFuture<QVector<VLayoutPiecePath> > futureInternalPaths = QtConcurrent::run(ConvertInternalPaths, piece, pattern);
     QFuture<QVector<QLineF> > futurePassmarksLines = QtConcurrent::run(piece, &VPiece::PassmarksLines, pattern);
@@ -270,6 +271,13 @@ VLayoutPiece VLayoutPiece::Create(const VPiece &piece, const VContainer *pattern
     det.SetForbidFlipping(piece.IsForbidFlipping());
     det.SetForceFlipping(piece.IsForceFlipping());
 
+    if (not futureSeamAllowanceValid.result())
+    {
+        const QString errorMsg = QObject::tr("Piece '%1'. Seam allowance is not valid.")
+                .arg(piece.GetName());
+        qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg;
+    }
+
     det.SetCountourPoints(futureMainPath.result(), piece.IsHideMainPath());
     det.SetSeamAllowancePoints(futureSeamAllowance.result(), piece.IsSeamAllowance(), piece.IsSeamAllowanceBuiltIn());
     det.SetInternalPaths(futureInternalPaths.result());
@@ -933,16 +941,8 @@ QGraphicsItem *VLayoutPiece::GetItem(bool textAsPaths) const
 //---------------------------------------------------------------------------------------------------------------------
 bool VLayoutPiece::IsLayoutAllowanceValid() const
 {
-    QVector<QPointF> piecePath;
-    if (IsSeamAllowance() && not IsSeamAllowanceBuiltIn())
-    {
-        piecePath = d->seamAllowance;
-    }
-    else
-    {
-        piecePath = d->contour;
-    }
-    return qFloor(qAbs(SumTrapezoids(d->layoutAllowance)/2.0)) >= qFloor(qAbs(SumTrapezoids(piecePath)/2.0));
+    QVector<QPointF> base = (IsSeamAllowance() && not IsSeamAllowanceBuiltIn()) ? d->seamAllowance : d->contour;
+    return VAbstractPiece::IsAllowanceValid(base, d->layoutAllowance);
 }
 
 //---------------------------------------------------------------------------------------------------------------------
diff --git a/src/libs/vpatterndb/vpiece.cpp b/src/libs/vpatterndb/vpiece.cpp
index fa8be8a85..5264efdc5 100644
--- a/src/libs/vpatterndb/vpiece.cpp
+++ b/src/libs/vpatterndb/vpiece.cpp
@@ -610,6 +610,12 @@ QPainterPath VPiece::PlaceLabelPath(const VContainer *data) const
     return path;
 }
 
+//---------------------------------------------------------------------------------------------------------------------
+bool VPiece::IsSeamAllowanceValid(const VContainer *data) const
+{
+    return VAbstractPiece::IsAllowanceValid(UniteMainPathPoints(data), SeamAllowancePoints(data));
+}
+
 //---------------------------------------------------------------------------------------------------------------------
 bool VPiece::IsInLayout() const
 {
diff --git a/src/libs/vpatterndb/vpiece.h b/src/libs/vpatterndb/vpiece.h
index a6ba94e7c..f482de936 100644
--- a/src/libs/vpatterndb/vpiece.h
+++ b/src/libs/vpatterndb/vpiece.h
@@ -112,6 +112,8 @@ public:
     QPainterPath PassmarksPath(const VContainer *data) const;
     QPainterPath PlaceLabelPath(const VContainer *data) const;
 
+    bool IsSeamAllowanceValid(const VContainer *data) const;
+
     bool IsInLayout() const;
     void SetInLayout(bool inLayout);
 
diff --git a/src/libs/vtools/tools/vtoolseamallowance.cpp b/src/libs/vtools/tools/vtoolseamallowance.cpp
index 884707f53..00280049e 100644
--- a/src/libs/vtools/tools/vtoolseamallowance.cpp
+++ b/src/libs/vtools/tools/vtoolseamallowance.cpp
@@ -1295,10 +1295,12 @@ void VToolSeamAllowance::RefreshGeometry(bool updateChildren)
     QFuture<QPainterPath > futurePassmarks = QtConcurrent::run(detail, &VPiece::PassmarksPath, this->getData());
 
     QFuture<QVector<QPointF> > futureSeamAllowance;
+    QFuture<bool> futureSeamAllowanceValid;
 
     if (detail.IsSeamAllowance())
     {
         futureSeamAllowance = QtConcurrent::run(detail, &VPiece::SeamAllowancePoints, this->getData());
+        futureSeamAllowanceValid = QtConcurrent::run(detail, &VPiece::IsSeamAllowanceValid, this->getData());
     }
 
     this->setPos(detail.GetMx(), detail.GetMy());
@@ -1327,6 +1329,12 @@ void VToolSeamAllowance::RefreshGeometry(bool updateChildren)
 
     if (detail.IsSeamAllowance() && not detail.IsSeamAllowanceBuiltIn())
     {
+        if (not futureSeamAllowanceValid.result())
+        {
+            const QString errorMsg = QObject::tr("Piece '%1'. Seam allowance is not valid.")
+                    .arg(detail.GetName());
+            qApp->IsPedantic() ? throw VException(errorMsg) : qWarning() << errorMsg;
+        }
         path.addPath(detail.SeamAllowancePath(futureSeamAllowance.result()));
         path.setFillRule(Qt::OddEvenFill);
         m_seamAllowance->setPath(path);