diff --git a/dumux/common/geometry/grahamconvexhull.hh b/dumux/common/geometry/grahamconvexhull.hh
index 67ef578a83aa328e10f94a0e54217a4d2063a17c..ffd326ac2818a680c4ac5e3963d37079ddb4d90d 100644
--- a/dumux/common/geometry/grahamconvexhull.hh
+++ b/dumux/common/geometry/grahamconvexhull.hh
@@ -40,10 +40,11 @@ namespace Dumux {
  *         +1   for a clockwise turn,
  *          0   if they are on one line (colinear)
  */
-int getOrientation(const Dune::FieldVector<double, 3>& a,
-                   const Dune::FieldVector<double, 3>& b,
-                   const Dune::FieldVector<double, 3>& c,
-                   const Dune::FieldVector<double, 3>& normal)
+template<class ctype>
+int getOrientation(const Dune::FieldVector<ctype, 3>& a,
+                   const Dune::FieldVector<ctype, 3>& b,
+                   const Dune::FieldVector<ctype, 3>& c,
+                   const Dune::FieldVector<ctype, 3>& normal)
 {
     const auto d = b-a;
     const auto e = c-b;
@@ -54,15 +55,28 @@ int getOrientation(const Dune::FieldVector<double, 3>& a,
 
 /*!
  * \brief Compute the points making up the convex hull around the given set of unordered points
- * \note We assume that all points are coplanar
- * \note this algorithm changes the order of the given points a bit
+ * \note We assume that all points are coplanar and there are no indentical points in the list
+ */
+template<class ctype>
+std::vector<Dune::FieldVector<ctype, 3>>
+grahamConvexHull2d3d(const std::vector<Dune::FieldVector<ctype, 3>>& points)
+{
+    auto copyPoints = points;
+    return grahamConvexHull2d3d(copyPoints);
+}
+
+/*!
+ * \brief Compute the points making up the convex hull around the given set of unordered points
+ * \note We assume that all points are coplanar and there are no indentical points in the list
+ * \note This algorithm changes the order of the given points a bit
  *       as they are unordered anyway this shouldn't matter too much
  */
-std::vector<Dune::FieldVector<double, 3>>
-grahamConvexHull2d3d(std::vector<Dune::FieldVector<double, 3>>& points)
+template<class ctype>
+std::vector<Dune::FieldVector<ctype, 3>>
+grahamConvexHull2d3d(std::vector<Dune::FieldVector<ctype, 3>>& points)
 {
-    using Point = Dune::FieldVector<double, 3>;
-    std::vector<Point> convexHull; convexHull.reserve(50);
+    using Point = Dune::FieldVector<ctype, 3>;
+    std::vector<Point> convexHull;
 
     // return empty convex hull
     if (points.size() < 3)
@@ -72,16 +86,35 @@ grahamConvexHull2d3d(std::vector<Dune::FieldVector<double, 3>>& points)
     if (points.size() == 3)
         return points;
 
-    // get the normal vector of the plane
+    // try to compute the normal vector of the plane
     const auto a = points[1] - points[0];
-    const auto b = points[2] - points[0];
+    auto b = points[2] - points[0];
     auto normal = Dumux::crossProduct(a, b);
-    normal /= normal.two_norm();
 
-    // find the element with the smallest y coordinate (if y is the same, smallest x coordinate)
-    auto minIt = std::min_element(points.begin(), points.end(),
-                                  [](const auto& a, const auto& b)
-                                  { return a[1] != b[1] ? a[1] < b[1] : a[0] < b[0]; });
+    // make sure the normal vector has non-zero length
+    std::size_t k = 2;
+    auto norm = normal.two_norm();
+    while (norm == 0.0 && k < points.size()-1)
+    {
+        b = points[++k];
+        normal = Dumux::crossProduct(a, b);
+        norm = normal.two_norm();
+    }
+
+    // if all given points are colinear -> return empty convex hull
+    if (norm == 0.0)
+        return convexHull;
+
+    using std::sqrt;
+    const auto eps = 1e-7*sqrt(norm);
+    normal /= norm;
+
+    // find the element with the smallest x coordinate (if x is the same, smallest y coordinate, and so on...)
+    auto minIt = std::min_element(points.begin(), points.end(), [&eps](const auto& a, const auto& b)
+    {
+        using std::abs;
+        return (abs(a[0]-b[0]) > eps ? a[0] < b[0] : (abs(a[1]-b[1]) > eps ? a[1] < b[1] : (a[2] < b[2])));
+    });
 
     // swap the smallest element to the front
     std::iter_swap(minIt, points.begin());
@@ -90,22 +123,23 @@ grahamConvexHull2d3d(std::vector<Dune::FieldVector<double, 3>>& points)
     // sort in counter-clockwise order around pivot point
     const auto pivot = points[0];
     std::sort(points.begin()+1, points.end(), [&](const auto& a, const auto& b)
-              {
-                  int order = getOrientation(pivot, a, b, normal);
-                  if (order == 0)
-                       return (a-pivot).two_norm() < (b-pivot).two_norm();
-                  else
-                       return (order == -1);
-              });
+    {
+        const int order = getOrientation(pivot, a, b, normal);
+        if (order == 0)
+             return (a-pivot).two_norm() < (b-pivot).two_norm();
+        else
+             return (order == -1);
+    });
 
     // push the first three points
+    convexHull.reserve(50);
     convexHull.push_back(points[0]);
     convexHull.push_back(points[1]);
     convexHull.push_back(points[2]);
 
     // This is the heart of the algorithm
-    // Pop_back until the last point in the queue forms a counter-clockwise oriented line
-    // with the new vertices. Then add new points to the queue.
+    // pop_back until the last point in the queue forms a counter-clockwise oriented line
+    // with the next two vertices. Then add these points to the queue.
     for (std::size_t i = 3; i < points.size(); ++i)
     {
         Point p = convexHull.back();
@@ -113,8 +147,19 @@ grahamConvexHull2d3d(std::vector<Dune::FieldVector<double, 3>>& points)
         // keep popping until the orientation a->b->currentp is counter-clockwise
         while (getOrientation(convexHull.back(), p, points[i], normal) != -1)
         {
-            p = convexHull.back();
-            convexHull.pop_back();
+            // make sure the queue doesn't get empty
+            if (convexHull.size() == 1)
+            {
+                // before we reach size-2 there has to be a good candidate
+                // as not all points are colinear (a non-zero plane normal exists)
+                assert(i < points.size()-2);
+                p = points[i++];
+            }
+            else
+            {
+                p = convexHull.back();
+                convexHull.pop_back();
+            }
         }
 
         // add back the last popped point and this point
@@ -130,10 +175,11 @@ grahamConvexHull2d3d(std::vector<Dune::FieldVector<double, 3>>& points)
  * \note Assumes all points of the convex hull are coplanar
  * \note This inserts a mid point and connects all corners with that point to triangles
  */
-std::vector<std::array<Dune::FieldVector<double, 3>, 3> >
-triangulateConvexHull(const std::vector<Dune::FieldVector<double, 3>>& convexHull)
+template<class ctype>
+std::vector<std::array<Dune::FieldVector<ctype, 3>, 3> >
+triangulateConvexHull(const std::vector<Dune::FieldVector<ctype, 3>>& convexHull)
 {
-    using Point = Dune::FieldVector<double, 3>;
+    using Point = Dune::FieldVector<ctype, 3>;
     using Triangle = std::array<Point, 3>;
 
     if (convexHull.size() < 3)
diff --git a/test/common/geometry/test_graham_convex_hull.cc b/test/common/geometry/test_graham_convex_hull.cc
index d08cf7f85940f1a655b91ffcc12cddfc87dcc4e7..150dd4015bc82e6977f6d36e6d1153c13e54b955 100644
--- a/test/common/geometry/test_graham_convex_hull.cc
+++ b/test/common/geometry/test_graham_convex_hull.cc
@@ -94,11 +94,11 @@ void writeVTKPolyData(const std::vector<Dune::FieldVector<double, 3>>& p,
          << "</VTKFile>\n";
 }
 
-int main(int argc, char* argv[])
+int main(int argc, char* argv[]) try
 {
     using Point = Dune::FieldVector<double, 3>;
     // create 100 random points
-    std::vector<Point> points(50);
+    std::vector<Point> points(100);
     // normal vector of the plane
     const Point normal({0.0, 1.0, 1.0});
     const Point origin({3.0, 0.0, 0.0});
@@ -121,5 +121,25 @@ int main(int argc, char* argv[])
 
     Dumux::writeVTKPolyDataTriangle(triangles, "triangulation");
 
+    // some specific tests for corner cases with colinear points
+    points = {{0.0,0.0,0.0}, {0.0,0.0,1.0}, {0.0,0.0,2.0}, {0.0,0.0,3.0}};
+    auto hull = Dumux::grahamConvexHull2d3d(points);
+    if (!(hull.empty())) DUNE_THROW(Dune::InvalidStateException, "False positive for finding a convex hull!");
+
+    points = {{0.0,0.0,0.0}, {0.0,0.0,1.0}, {0.0,0.0,2.0}, {0.0,0.0,3.0}, {0.0,0.0,4.0}, {2.0,3.0,3.0}};
+    hull = Dumux::grahamConvexHull2d3d(points);
+    if (hull.empty()) DUNE_THROW(Dune::InvalidStateException, "Didn't find convex hull!");
+
+    points = {{2.0,3.0,3.0}, {0.0,0.0,4.0}, {0.0,0.0,0.0}, {0.0,0.0,1.0}, {0.0,0.0,2.0}, {0.0,0.0,3.0}};
+    hull = Dumux::grahamConvexHull2d3d(points);
+    if (hull.empty()) DUNE_THROW(Dune::InvalidStateException, "Didn't find convex hull!");
+
     return 0;
 }
+// //////////////////////////////////
+//   Error handler
+// /////////////////////////////////
+catch (const Dune::Exception& e) {
+    std::cout << e << std::endl;
+    return 1;
+}