Weird face issue when creating custom meshes

So I have been experimenting with custom meshes recently.
I came up with this code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TerrainChunk : MonoBehaviour
{
    void Start ()
    {
        Vector3[] vertices =
        {
           new Vector3(0,0,0),
           new Vector3(1,0,0),
           new Vector3(1,1,0),
           new Vector3(0,1,0),
           new Vector3(0,1,1),
           new Vector3(1,1,1),
           new Vector3(1,0,1),
           new Vector3(0,0,1), 
        };
        int[] triangles =
        {
            //front face
            0,2,1,
            0,3,2,
            //top face
            2,3,4,
            2,4,5,
            //right face
            1,2,5,
            1,5,6,
            //back face
            5,4,7,
            5,7,6,
            //bottom face
            0,6,7,
            0,1,6
        };
       
        GameObject cube = new GameObject();
        cube.AddComponent<MeshFilter>();
        cube.AddComponent<MeshRenderer>();
        Mesh mesh = cube.GetComponent<MeshFilter>().mesh;
        mesh.Clear();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.RecalculateNormals();

        for( int x=0 ; x<16 ; x++ )
        for( int z=0 ; z<16 ; z++ )
        {
            Instantiate( cube , new Vector3(x,0,z) , Quaternion.identity );
        }
    }
}

However, there is this weird issue with some of the faces:

Did I do something wrong in the code? I’m also planning on combining these meshes after I finish everything

You forgot to add X- face

using UnityEngine;

public class TerrainChunk : MonoBehaviour
{
    [SerializeField] Material _material;
    void Start ()
    {
        Vector3[] vertices =
        {
           new Vector3(0,0,0),// 0
           new Vector3(1,0,0),// 1
           new Vector3(1,1,0),// 2
           new Vector3(0,1,0),// 3
           new Vector3(0,1,1),// 4
           new Vector3(1,1,1),// 5
           new Vector3(1,0,1),// 6
           new Vector3(0,0,1),// 7
        };
        ///      5--------2
        ///     /|       /|
        ///    / |      / |
        ///   4--------3  |
        ///   |  |     |  |
        ///   |  6---- | -1        Y
        ///   | /      | /         | X
        ///   |/       |/          |/
        ///   7--------0       Z---+
        int[] triangles =
        {
            1,2,5, 1,5,6,// X+ face
            7,4,3, 7,3,0,// X- face

            2,3,4, 2,4,5,// Y+ face
            0,1,6, 0,6,7,// Y- face

            6,5,4, 6,4,7,// Z+ face
            0,3,2, 0,2,1,// Z- face
        };
       
        Mesh mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.RecalculateNormals();

        GameObject tempPrefab = new GameObject("cube");
        MeshFilter mf = tempPrefab.AddComponent<MeshFilter>();
        mf.sharedMesh = mesh;
        MeshRenderer mr = tempPrefab.AddComponent<MeshRenderer>();
        mr.sharedMaterial = _material;

        for( int x = 0 ; x<16 ; x++ )
        for( int z = 0 ; z<16 ; z++ )
        {
            Instantiate(tempPrefab , new Vector3(x , 0 , z) , Quaternion.identity);
        }

        Destroy( tempPrefab );
    }
}

Your next step is to to this - merge them into a single mesh like this:

using System.Collections.Generic;
using UnityEngine;

public class TerrainChunk : MonoBehaviour
{
    [SerializeField] MeshFilter _meshFilter;
    [SerializeField] Vector3 _cubeSize = Vector3.one;
    void Start ()
    {
        ///      C--------D
        ///     /|       /|
        ///    / |      / |
        ///   B--------A  |
        ///   |  |     |  |
        ///   |  G---- | -H        Y
        ///   | /      | /         | X
        ///   |/       |/          |/
        ///   F--------E       Z---+
        Vector3 A = Vector3.Scale( new Vector3(0,1,0) , _cubeSize );// Vector3.Scale is Vector3*Vector3 multiplication
        Vector3 B = Vector3.Scale( new Vector3(0,1,1) , _cubeSize );
        Vector3 C = Vector3.Scale( new Vector3(1,1,1) , _cubeSize );
        Vector3 D = Vector3.Scale( new Vector3(1,1,0) , _cubeSize );
        Vector3 E = Vector3.Scale( new Vector3(0,0,0) , _cubeSize );
        Vector3 F = Vector3.Scale( new Vector3(0,0,1) , _cubeSize );
        Vector3 G = Vector3.Scale( new Vector3(1,0,1) , _cubeSize );
        Vector3 H = Vector3.Scale( new Vector3(1,0,0) , _cubeSize );

        Vector3[] rightVertices = { H,D,C,G };// x+ face
        Vector3[] leftVertices = { F,B,A,E };// x- face 
        Vector3[] upVertices = { A,B,C,D };// y+ face
        Vector3[] downVertices = { F,E,H,G };// y- face
        Vector3[] forwardVertices = { G,C,B,F };// z+ face
        Vector3[] backVertices = { E,A,D,H };// z- face

        Vector3[] rightNormals = { Vector3.right, Vector3.right, Vector3.right, Vector3.right };// x+ face
        Vector3[] leftNormals = { Vector3.left, Vector3.left, Vector3.left, Vector3.left };// x- face
        Vector3[] upNormals = { Vector3.up, Vector3.up, Vector3.up, Vector3.up };// y+ face
        Vector3[] downNormals = { Vector3.down, Vector3.down, Vector3.down, Vector3.down };// y- face
        Vector3[] forwardNormals = { Vector3.forward, Vector3.forward, Vector3.forward, Vector3.forward };// z+ face
        Vector3[] backNormals = { Vector3.back, Vector3.back, Vector3.back, Vector3.back };// z- face

        Vector2[] rightUV = { new Vector2(0,0),new Vector2(0,0.5f),new Vector2(0.5f,0.5f),new Vector2(0.5f,0), };// x+
        Vector2[] leftUV = { new Vector2(0,0),new Vector2(0,0.5f),new Vector2(0.5f,0.5f),new Vector2(0.5f,0), };// x-
        Vector2[] upUV = { new Vector2(0,0.5f),new Vector2(0,1),new Vector2(0.5f,1),new Vector2(0.5f,0.5f), };// y+
        Vector2[] downUV = { new Vector2(0.5f,0.5f),new Vector2(0.5f,1),new Vector2(1,1),new Vector2(1,0.5f), };// y-
        Vector2[] forwardUV = { new Vector2(0.5f,0),new Vector2(0.5f,0.5f),new Vector2(1,0.5f),new Vector2(1,0), };// z+
        Vector2[] backUV = { new Vector2(0.5f,0),new Vector2(0.5f,0.5f),new Vector2(1,0.5f),new Vector2(1,0), };// z-

        int[] faceIndices = { 0,1,2, 0,2,3 };// assumes identical order of vertices
        
        List<Vector3> vertices = new();
        List<Vector3> normals = new();
        List<Vector2> uvs = new();
        List<int> indices = new();

        int index = 0;// you need to store 
        for( int y=0 ; y<1 ; y++ )
        for( int x=0 ; x<16 ; x++ )
        for( int z=0 ; z<16 ; z++ )
        {
            Vector3 cellPosition = Vector3.Scale( new Vector3(x,y,z) , _cubeSize );// Vector3.Scale is Vector3*Vector3 multiplication

            // x+ / right face
            if( true )// TODO: false when there is a cube in this direction
            {
                foreach( Vector3 vertex in rightVertices )
                    vertices.Add( cellPosition + vertex );
                
                normals.AddRange( rightNormals );
                uvs.AddRange( rightUV );
                
                foreach( int i in faceIndices )
                    indices.Add( index+i );
                index += rightVertices.Length;
            }

            // x- / left face
            if( true )// TODO: false when there is a cube in this direction
            {
                foreach( Vector3 vertex in leftVertices )
                    vertices.Add( cellPosition + vertex );

                normals.AddRange( leftNormals );
                uvs.AddRange( leftUV );

                foreach( int i in faceIndices )
                    indices.Add( index+i );
                index += leftVertices.Length;
            }

            // y+ / up face
            if( true )// TODO: false when there is a cube in this direction
            {
                foreach( Vector3 vertex in upVertices )
                    vertices.Add( cellPosition + vertex );

                normals.AddRange( upNormals );
                uvs.AddRange( upUV );

                foreach( int i in faceIndices )
                    indices.Add( index+i );
                index += upVertices.Length;
            }
            
            // y- / down face
            if( true )// TODO: false when there is a cube in this direction
            {
                foreach( Vector3 vertex in downVertices )
                    vertices.Add( cellPosition + vertex );

                normals.AddRange( downNormals );
                uvs.AddRange( downUV );

                foreach( int i in faceIndices )
                    indices.Add( index+i );
                index += downVertices.Length;
            }

            // z+ / forward face
            if( true )// TODO: false when there is a cube in this direction
            {
                foreach( Vector3 vertex in forwardVertices )
                    vertices.Add( cellPosition + vertex );

                normals.AddRange( forwardNormals );
                uvs.AddRange( forwardUV );

                foreach( int i in faceIndices )
                    indices.Add( index+i );
                index += forwardVertices.Length;
            }

            // z- / back face
            if( true )// TODO: false when there is a cube in this direction
            {
                foreach( Vector3 vertex in backVertices )
                    vertices.Add( cellPosition + vertex );

                normals.AddRange( backNormals );
                uvs.AddRange( backUV );

                foreach( int i in faceIndices )
                    indices.Add( index+i );
                index += backVertices.Length;
            }
        }

        Mesh mesh = new Mesh();
        mesh.name = "procedural mesh";
        mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;// higher mesh complexity limit
        mesh.SetVertices( vertices );
        mesh.SetNormals( normals );
        mesh.SetUVs( 0 , uvs );
        mesh.SetTriangles( indices , 0 );
        _meshFilter.sharedMesh = mesh;
    }
}