how do I readPixels() an R32F texture in webgl2?

I am using WebGL2 to render 32-bit floating point values into a 2D texture with only one channel (red). After the draw call, I want to read those values in JavaScript.
The following gives GL_INVALID_OPERATION: Invalid format and type combination. because of that last gl.readPixels line.

const gl = document.createElement("canvas").getContext("webgl2");
if(!gl.getExtension("EXT_color_buffer_float")) {
    throw "float";
}

// ... compile program ...

gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    -1, -1,
    1, -1,
    1, 1,
    -1, -1,
    -1, 1,
    1, 1,
]), gl.STATIC_DRAW);
const texture = gl.createTexture();
const framebuffer = gl.createFramebuffer();
gl.viewport(0, 0, width, height);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R32F, width, height, 0, gl.RED, gl.FLOAT, null);
gl.useProgram(program);
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.drawArrays(gl.TRIANGLES, 0, 6);
const pixels = new Float32Array(width * height);
gl.readPixels(0, 0, width, height, gl.RED, gl.FLOAT, pixels);

How do I read from an R32F texture?