OpenRA/OpenRA · critical · InvalidProgramException

Failed to initialize an OpenGL debug message callback.

Error message

Failed to initialize an OpenGL debug message callback.

What it means

Thrown when setting up the OpenGL debug-message callback fails: binding glDebugMessageCallback(+suffix), glDebugMessageInsert, enabling GL_DEBUG_OUTPUT / GL_DEBUG_OUTPUT_SYNCHRONOUS, or registering the callback raised an exception. InvalidProgramException wraps the inner exception. This is a best-effort feature (driver-bug workaround path) whose failure still aborts init.

Source

Thrown at OpenRA.Platforms.Default/OpenGL.cs:560

			// Setup the debug message callback handler
			if (Features.HasFlag(GLFeatures.DebugMessagesCallback))
			{
				try
				{
					var suffix = Profile == GLProfile.Embedded ? "KHR" : "";
					glDebugMessageCallback = Bind<DebugMessageCallback>("glDebugMessageCallback" + suffix);
					glDebugMessageInsert = Bind<DebugMessageInsert>("glDebugMessageInsert" + suffix);

					glEnable(GL_DEBUG_OUTPUT);
					glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

					// Need to keep a reference to the callback so it doesn't get garbage collected
					DebugMessageHandle = DebugMessageHandler;
					glDebugMessageCallback(DebugMessageHandle, IntPtr.Zero);
				}
				catch (Exception e)
				{
					throw new InvalidProgramException("Failed to initialize an OpenGL debug message callback.", e);
				}
			}

			Console.WriteLine("OpenGL renderer: " + glGetString(GL_RENDERER));
			Console.WriteLine("OpenGL version: " + glGetString(GL_VERSION));

			try
			{
				glFlush = Bind<Flush>("glFlush");
				glViewport = Bind<Viewport>("glViewport");
				glClear = Bind<Clear>("glClear");
				glClearColor = Bind<ClearColor>("glClearColor");
				glFinish = Bind<Finish>("glFinish");
				glCreateProgram = Bind<CreateProgram>("glCreateProgram");
				glUseProgram = Bind<UseProgram>("glUseProgram");
				glGetProgramiv = Bind<GetProgramiv>("glGetProgramiv");
				glCreateShader = Bind<CreateShader>("glCreateShader");
				glShaderSource = Bind<ShaderSource>("glShaderSource");

View on GitHub (pinned to a520984d91)

Solutions

  1. Force-disable the debug callback via Game.Settings.Graphics.DisableGLDebugMessageCallback (the code path that trips this only runs when that flag is false).
  2. Update GPU drivers to fix the broken debug-callback entry points.
  3. If on Linux + AMD/Radeon, the code already auto-disables this; on other affected drivers, set the disable flag.

Example fix

// before - debug callback enabled, throws on buggy driver
Game.Settings.Graphics.DisableGLDebugMessageCallback = false;
// after - opt out of the buggy debug-callback path
Game.Settings.Graphics.DisableGLDebugMessageCallback = true;
Defensive patterns

Strategy: validation

Validate before calling

// Opt out of the debug-callback path before OpenGL.Initialize runs
Game.Settings.Graphics.DisableGLDebugMessageCallback = true;

Try / catch

if (!Game.Settings.Graphics.DisableGLDebugMessageCallback)
{
    try { OpenGL.Initialize(); }
    catch (InvalidProgramException ex) when (ex.Message.Contains("debug message callback"))
    {
        Game.Settings.Graphics.DisableGLDebugMessageCallback = true;
        OpenGL.Initialize(); // retry without the callback
    }
}

Prevention

When it happens

Trigger: When the GL feature set includes DebugMessagesCallback, Initialize sets up the callback; if binding or callback registration throws, the catch rethrows. More common on certain drivers that advertise the extension but misbehave.

Common situations: Driver advertises KHR_debug / ARB_debug_output but the function pointers are broken; a driver bug when registering the synchronous callback; platform-specific GL loader quirk; the suffix (ARB/KHR) resolution picking the wrong entry point.

Related errors


AI-assisted analysis of OpenRA/OpenRA@a520984d91 (2026-08-13). Data as JSON: /api/errors/b03e983c016d2331. Report an issue: GitHub.