diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 3e6a3a50..4196ad4b 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -1045,60 +1045,63 @@ void SimpleCameraData::updateScalerCrop(std::optional<Rectangle> crop)
 		properties_.set(properties::ScalerCropMaximum, *crop);
 		return;
 	}
 
 	if (!properties_.contains(properties::ScalerCropMaximum.id()))
 		return;
 
 	ControlList updatedProperties = properties_;
 	updatedProperties.clear();
 	for (const auto &[id, value] : properties_) {
 		if (id != properties::ScalerCropMaximum.id())
 			updatedProperties.set(id, value);
 	}
 	properties_ = std::move(updatedProperties);
 }
 
 void SimpleCameraData::tryCompleteRequest(Request *request)
 {
 	if (request->hasPendingBuffers())
 		return;
 
 	SimpleFrameInfo *info = frameInfo_.find(request->sequence());
 	if (!info) {
 		/* Something is really wrong, let's return. */
 		return;
 	}
 
 	if (info->metadataRequired && !info->metadataProcessed)
 		return;
 
+	if (scalerCrop_)
+		request->_d()->metadata().set(controls::ScalerCrop, *scalerCrop_);
+
 	frameInfo_.destroy(info->frame);
 	pipe()->completeRequest(request);
 }
 
 void SimpleCameraData::conversionInputDone(FrameBuffer *buffer)
 {
 	if (rawStream_) {
 		/* Complete the input buffer as with raw-only processing. */
 		Request *request = buffer->request();
 		if (pipe()->completeBuffer(request, buffer))
 			tryCompleteRequest(request);
 	} else {
 		/* Queue the input buffer back for capture. */
 		video_->queueBuffer(buffer);
 	}
 }
 
 void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)
 {
 	SimplePipelineHandler *pipe = SimpleCameraData::pipe();
 
 	/* Complete the buffer and the request. */
 	Request *request = buffer->request();
 	if (pipe->completeBuffer(request, buffer))
 		tryCompleteRequest(request);
 }
 
 void SimpleCameraData::ispStatsReady(uint32_t frame, uint32_t bufferId)
 {
 	swIsp_->processStats(frame, bufferId,
