diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp
index 7b9e02d9..cfe41447 100644
--- a/src/libcamera/software_isp/debayer_egl.cpp
+++ b/src/libcamera/software_isp/debayer_egl.cpp
@@ -33,6 +33,34 @@ namespace libcamera {
  * Implements an EGL shader based debayering solution.
  */
 
+/**
+ * \brief Probe whether EGL surfaceless rendering is available
+ *
+ * Performs a lightweight check by attempting to obtain an EGL display using
+ * EGL_PLATFORM_SURFACELESS_MESA and initialising it. The display is
+ * immediately released so that no resources are leaked. This allows the
+ * caller to decide at construction time whether to instantiate DebayerEGL
+ * or fall back to DebayerCpu.
+ *
+ * \return true if EGL surfaceless rendering is available, false otherwise
+ */
+bool DebayerEGL::isEGLAvailable()
+{
+	if (!eglBindAPI(EGL_OPENGL_ES_API))
+		return false;
+
+	EGLDisplay display = eglGetPlatformDisplay(EGL_PLATFORM_SURFACELESS_MESA,
+						    EGL_DEFAULT_DISPLAY,
+						    nullptr);
+	if (display == EGL_NO_DISPLAY)
+		return false;
+
+	EGLBoolean ret = eglInitialize(display, nullptr, nullptr);
+	eglTerminate(display);
+
+	return ret == EGL_TRUE;
+}
+
 /**
  * \brief Construct a DebayerEGL object
  * \param[in] stats Statistics processing object
diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h
index 141fb288..945125cd 100644
--- a/src/libcamera/software_isp/debayer_egl.h
+++ b/src/libcamera/software_isp/debayer_egl.h
@@ -39,6 +39,8 @@ class CameraManager;
 class DebayerEGL : public Debayer
 {
 public:
+	static bool isEGLAvailable();
+
 	DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const CameraManager &cm);
 	~DebayerEGL();
 
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index 781cf02f..403efbdb 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -119,8 +119,14 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
 		}
 	}
 
-	if (!softISPMode || softISPMode == "gpu")
-		debayer_ = std::make_unique<DebayerEGL>(std::move(stats), cm);
+	if (!softISPMode || softISPMode == "gpu") {
+		if (DebayerEGL::isEGLAvailable()) {
+			debayer_ = std::make_unique<DebayerEGL>(std::move(stats), cm);
+		} else {
+			LOG(SoftwareIsp, Info)
+				<< "EGL not available, falling back to CPU debayer";
+		}
+	}
 
 #endif
 	if (!debayer_)
