diff --git a/src/libslic3r/GCode/SeamPlacer.cpp b/src/libslic3r/GCode/SeamPlacer.cpp
index 65bd29e63..004a42a53 100644
--- a/src/libslic3r/GCode/SeamPlacer.cpp
+++ b/src/libslic3r/GCode/SeamPlacer.cpp
@@ -1226,6 +1226,7 @@ void SeamPlacer::align_seam_points(const PrintObject *po, const SeamPlacerImpl::
                 Vec3f final_position = t * current_pos + (1 - t) * to_3d(fitted_pos, current_pos.z());
 
                 Perimeter &perimeter = layers[pair.first].points[pair.second].perimeter;
+                perimeter.seam_index = pair.second;
                 perimeter.final_seam_position = final_position;
                 perimeter.finalized = true;
             }
@@ -1358,11 +1359,13 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool extern
     }
 
     Vec3f seam_position;
+    size_t seam_index;
     if (const Perimeter &perimeter = layer_perimeters.points[closest_perimeter_point_index].perimeter;
     perimeter.finalized) {
         seam_position = perimeter.final_seam_position;
+        seam_index = perimeter.seam_index;
     } else {
-        size_t seam_index =
+        seam_index =
                 po->config().seam_position == spNearest ?
                         pick_nearest_seam_point_index(layer_perimeters.points, perimeter.start_index,
                                 unscaled<float>(last_pos)) :
@@ -1370,12 +1373,45 @@ void SeamPlacer::place_seam(const Layer *layer, ExtrusionLoop &loop, bool extern
         seam_position = layer_perimeters.points[seam_index].position;
     }
 
-    auto seam_point = Point::new_scale(seam_position.x(), seam_position.y());
+    Point seam_point = Point::new_scale(seam_position.x(), seam_position.y());
 
-    if (!loop.split_at_vertex(seam_point))
-// The point is not in the original loop.
-// Insert it.
+    if (const SeamCandidate &perimeter_point = layer_perimeters.points[seam_index];
+    (po->config().seam_position == spNearest || po->config().seam_position == spAligned) &&
+            loop.role() == ExtrusionRole::erPerimeter && //Hopefully internal perimeter
+            (seam_position - perimeter_point.position).squaredNorm() < 4.0f && // seam is on perimeter point
+            perimeter_point.local_ccw_angle < -EPSILON // In concave angles
+                    ) { // In this case, we are at internal perimeter, where the external perimeter has seam in concave angle. We want to align
+            // the internal seam into the concave corner, and not on the perpendicular projection on the closest edge (which is what the split_at function does)
+        size_t index_of_prev =
+                seam_index == perimeter_point.perimeter.start_index ?
+                                                                      perimeter_point.perimeter.end_index :
+                                                                      seam_index - 1;
+        size_t index_of_next =
+                seam_index == perimeter_point.perimeter.end_index ?
+                                                                    perimeter_point.perimeter.start_index :
+                                                                    seam_index + 1;
+
+        Vec2f dir_to_middle =
+                ((perimeter_point.position - layer_perimeters.points[index_of_prev].position).head<2>().normalized()
+                        + (perimeter_point.position - layer_perimeters.points[index_of_next].position).head<2>().normalized())
+                        * 0.5;
+
+        auto [_, projected_point] = loop.get_closest_path_and_point(seam_point, true);
+        //get closest projected point, determine depth of the seam point.
+        float depth = (float) unscale(Point(seam_point - projected_point)).norm();
+        float angle_factor = cos(-perimeter_point.local_ccw_angle / 2.0f); // There are some nice geometric identities in determination of the correct depth of new seam point.
+        //overshoot the target depth, in concave angles it will correctly snap to the corner; TODO: find out why such big overshoot is needed.
+        constexpr float sq2 = sqrt(2.0f);
+        Vec2f final_pos = perimeter_point.position.head<2>() + (sq2 * depth / angle_factor) * dir_to_middle;
+        seam_point = Point::new_scale(final_pos.x(), final_pos.y());
+    }
+
+    if (!loop.split_at_vertex(seam_point)) {
+        // The point is not in the original loop.
+        // Insert it.
         loop.split_at(seam_point, true);
+    }
+
 }
 
 } // namespace Slic3r