Three different complaints that sound like one
Slicers reject models for several unrelated reasons and describe them all in roughly the same language, which is why the same fix keeps not working. It is worth separating them, because each has a different cause and a different remedy.
Not watertight means the surface has a boundary: somewhere there is an edge with a triangle on one side and nothing on the other. The surface does not enclose a volume, so the slicer cannot tell inside from outside and has nothing to fill. This is what people mean by a hole.
Non-manifold is a different failure. Here the surface has no gap, but some edge is shared by three or more faces β an internal wall left behind by a boolean, two solids fused along a face, a zero-thickness fin. At such an edge the question "which side is inside?" has no single answer, and the slicer cannot follow the surface through it.
Inverted or flipped normals means the winding order is wrong. Each triangle lists its corners in an order that defines which face points outward. When neighbouring triangles disagree, the surface has patches turned inside out; when the entire model is wound backwards, it is watertight and manifold and still unprintable, because the slicer will try to print everything except your object.
Why the number in the error message is not an error code
A slicer reporting "6106 non-manifold edges" is not giving you a code to look up. It is counting. Six thousand of them will typically be one seam where two halves of a model were joined without merging, and the useful question is not how many edges are wrong but how many separate places they form. Grouping the edges into connected clusters usually turns a five-figure number into three or four locations, each of which can be inspected and fixed in a couple of minutes.
How the check is done here
The file is parsed into a flat list of triangles, then the vertices are welded: coordinates that land on the same point within a tolerance derived from the model's own size are collapsed onto a single shared vertex. This step is mandatory rather than an optimisation. STL has no concept of a shared vertex β two triangles that meet along an edge simply repeat the same coordinates β so before welding there is no such thing as a neighbour, and every edge in the file looks like a boundary.
Once the mesh is welded, each edge is counted. An edge used by exactly two faces is normal. An edge used once is a boundary edge, and chaining boundary edges end to end produces the rings that are the actual holes. An edge used three or more times is non-manifold; those are clustered by shared vertices into the regions they occupy. Winding is checked at the same time: on a consistently wound surface, the two faces meeting at an edge traverse it in opposite directions, so any edge traversed the same way twice marks a flipped neighbour.
Volume comes from summing signed tetrahedra between each triangle and the origin. The magnitude is the enclosed volume, useful for estimating material; the sign is the interesting part, because a closed surface with negative volume is wound inside-out.
What this deliberately does not do
Self-intersection is not reported. Detecting every pair of crossing triangles is quadratic in the triangle count without a spatial index, and on a model large enough to matter it would lock the tab for minutes to produce a list nobody can act on. Wall thickness is not measured either: the answer depends on your nozzle, your material and your orientation on the plate, and a number produced without knowing those is worse than no number.
Nothing is repaired. Filling a hole means inventing surface that was never modelled, and on a decorative print that is fine while on a functional part it can silently move a hole or a mating face. The position and size of each defect are reported so the fix can be made where the design actually lives.