diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 0da167a7..e0a5d03d 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -358,10 +358,13 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF
 
 	/*
 	 * Set all raw streams to the Raw color space, and make a note of the
-	 * largest non-raw stream with a defined color space (if there is one).
+	 * largest non-raw stream with a defined color space (if there is one), and
+	 * also the largest stream with YCbCr encoding information.
 	 */
 	std::optional<ColorSpace> colorSpace;
+	std::optional<ColorSpace> ycbcrColorSpace;
 	Size size;
+	Size ycbcrSize;
 
 	for (auto [i, cfg] : utils::enumerate(config_)) {
 		if (!cfg.colorSpace)
@@ -370,22 +373,56 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF
 		if (cfg.colorSpace->adjust(cfg.pixelFormat))
 			status = Adjusted;
 
-		if (cfg.colorSpace != ColorSpace::Raw && cfg.size > size) {
+		if (cfg.colorSpace == ColorSpace::Raw)
+			continue;
+
+		if (cfg.size > size) {
 			colorSpace = cfg.colorSpace;
 			size = cfg.size;
 		}
+
+		if (cfg.colorSpace->ycbcrEncoding != ColorSpace::YcbcrEncoding::None &&
+		    cfg.size > ycbcrSize) {
+			ycbcrColorSpace = cfg.colorSpace;
+			ycbcrSize = cfg.size;
+		}
 	}
 
 	if (!colorSpace || !(flags & ColorSpaceFlag::StreamsShareColorSpace))
 		return status;
 
-	/* Make all output color spaces the same, if requested. */
+	/*
+	 * Make all output color spaces the same, if requested. Note that when sharing like
+	 * this, we copy the primaries and transfer function from the principal stream
+	 * (the variable "colorSpace") but we mustn't use its ycbcrEncoding or range because
+	 * it may be an RGB stream. So we take these fields instead from the "ycbcrColorSpace".
+	 */
 	for (auto &cfg : config_) {
-		if (cfg.colorSpace != ColorSpace::Raw &&
-		    cfg.colorSpace != colorSpace) {
+		if (!cfg.colorSpace) {
 			cfg.colorSpace = colorSpace;
 			status = Adjusted;
 		}
+
+		if (cfg.colorSpace == ColorSpace::Raw)
+			continue;
+
+		/* Ensure the primaries and transferFunction match the "main" stream. */
+		if (cfg.colorSpace->primaries != colorSpace->primaries ||
+		    cfg.colorSpace->transferFunction != colorSpace->transferFunction) {
+			cfg.colorSpace->primaries = colorSpace->primaries;
+			cfg.colorSpace->transferFunction = colorSpace->transferFunction;
+			status = Adjusted;
+		}
+
+		if (cfg.colorSpace->ycbcrEncoding != ColorSpace::YcbcrEncoding::None) {
+			/* Set these from the ycbcrColorSpace (which we note must exist). */
+			if (ycbcrColorSpace->ycbcrEncoding != cfg.colorSpace->ycbcrEncoding ||
+			    ycbcrColorSpace->range != cfg.colorSpace->range) {
+				cfg.colorSpace->ycbcrEncoding = ycbcrColorSpace->ycbcrEncoding;
+				cfg.colorSpace->range = ycbcrColorSpace->range;
+				status = Adjusted;
+			}
+		}
 	}
 
 	return status;
