diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h
index d006bf68..6efcb0db 100644
--- a/include/libcamera/internal/v4l2_device.h
+++ b/include/libcamera/internal/v4l2_device.h
@@ -41,6 +41,8 @@ public:
 	int setFrameStartEnabled(bool enable);
 	Signal<uint32_t> frameStart;
 
+	void refreshControls();
+
 protected:
 	V4L2Device(const std::string &deviceNode);
 	~V4L2Device();
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index f7ed91d9..9f99ce3e 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -796,6 +796,13 @@ int CameraSensor::sensorInfo(CameraSensorInfo *info) const
 	info->bitsPerPixel = format.bitsPerPixel();
 	info->outputSize = format.size;
 
+	/*
+	 * Some controls, specifically the vblanking, may have different min
+	 * or max values if the sensor format has been changed since it was
+	 * opened, so be sure to update them first.
+	 */
+	subdev_->refreshControls();
+
 	/*
 	 * Retrieve the pixel rate, line length and minimum/maximum frame
 	 * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE,
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
index decd19ef..6d396f89 100644
--- a/src/libcamera/v4l2_device.cpp
+++ b/src/libcamera/v4l2_device.cpp
@@ -514,6 +514,32 @@ void V4L2Device::listControls()
 	controls_ = std::move(ctrls);
 }
 
+/*
+ * \brief Update the control information that was previously stored by
+ * listControls(). Some parts of this information, such as min and max
+ * values of some controls, are liable to change when a new format is set.
+ */
+void V4L2Device::refreshControls()
+{
+	for (auto &controlId : controlIds_) {
+		unsigned int id = controlId->id();
+
+		struct v4l2_query_ext_ctrl ctrl = {};
+		ctrl.id = id;
+
+		if (ioctl(VIDIOC_QUERY_EXT_CTRL, &ctrl)) {
+			LOG(V4L2, Debug)
+				<< "Could not refresh control "
+				<< utils::hex(ctrl.id);
+			continue;
+		}
+
+		/* Assume these are present - listControls() made them. */
+		controlInfo_[id] = ctrl;
+		controls_.at(controlId.get()) = V4L2ControlInfo(ctrl);
+	}
+}
+
 /*
  * \brief Update the value of the first \a count V4L2 controls in \a ctrls using
  * values in \a v4l2Ctrls
