Correct parameters for rendering 16-bit volumetric data

I am rendering a grayscale volumetric with each point containing 16-bit integer data, so I am using the following textures.

Data Generating part, this part will create some spheres

export function generateVolume(volume: Volume) {
  const size = volume.width * volume.height * volume.depth;
  const points = [
    [0.5, 0.5, 0.5, 0.4],
    [0, 0, 0, 0.2],
  ];
  volume.data = new Uint16Array(size);

  for (var i = 0; i < volume.width; i++) {
    for (var j = 0; j < volume.height; j++) {
      for (var k = 0; k < volume.depth; k++) {
        const x = i / volume.width;
        const y = j / volume.height;
        const z = k / volume.depth;

        for (var p = 0; p < points.length; p++) {
          const [px, py, pz, intensity] = points[p];
          const distance = Math.sqrt(
            (x - px) ** 2 + (y - py) ** 2 + (z - pz) ** 2
          );
          const value = Math.min(distance / intensity, 1);
          const index = i + j * volume.width + k * volume.width * volume.height;
          volume.data[index] = Math.max(volume.data[index], (1 - value) * 255);
        }
      }
    }
  }
}

Texture binding

const location = gl.getUniformLocation(program, "u_volume");
gl.activeTexture(gl.TEXTURE0 + index);gl.bindTexture(gl.TEXTURE_3D, texture);
gl.texImage3D(
        gl.TEXTURE_3D,
        0,
        gl.R16UI,
        volume.width,
        volume.height,
        volume.depth,
        0,
        gl.RED_INTEGER,
        gl.UNSIGNED_SHORT,
        volume.data
      );
gl.uniform1i(location, index);

then I get this error : [.WebGL-0xd1402387100] GL_INVALID_OPERATION: Mismatch between texture format and sampler type (signed/unsigned/float/shadow)
What parameters should I actually be using?